Edit on GitHub

Expressions

Every AST node in SQLGlot is represented by a subclass of Expression.

This module contains the implementation of all supported Expression types. Additionally, it exposes a number of helper functions, which are mainly used to programmatically build SQL expressions, such as select.


   1"""
   2## Expressions
   3
   4Every AST node in SQLGlot is represented by a subclass of `Expression`.
   5
   6This module contains the implementation of all supported `Expression` types. Additionally,
   7it exposes a number of helper functions, which are mainly used to programmatically build
   8SQL expressions, such as `sqlglot.expressions.select`.
   9
  10----
  11"""
  12
  13from __future__ import annotations
  14
  15import datetime
  16import math
  17import numbers
  18import re
  19import textwrap
  20import typing as t
  21from collections import deque
  22from copy import deepcopy
  23from enum import auto
  24from functools import reduce
  25
  26from sqlglot.errors import ErrorLevel, ParseError
  27from sqlglot.helper import (
  28    AutoName,
  29    camel_to_snake_case,
  30    ensure_collection,
  31    ensure_list,
  32    seq_get,
  33    subclasses,
  34)
  35from sqlglot.tokens import Token
  36
  37if t.TYPE_CHECKING:
  38    from sqlglot._typing import E, Lit
  39    from sqlglot.dialects.dialect import DialectType
  40
  41
  42class _Expression(type):
  43    def __new__(cls, clsname, bases, attrs):
  44        klass = super().__new__(cls, clsname, bases, attrs)
  45
  46        # When an Expression class is created, its key is automatically set to be
  47        # the lowercase version of the class' name.
  48        klass.key = clsname.lower()
  49
  50        # This is so that docstrings are not inherited in pdoc
  51        klass.__doc__ = klass.__doc__ or ""
  52
  53        return klass
  54
  55
  56SQLGLOT_META = "sqlglot.meta"
  57TABLE_PARTS = ("this", "db", "catalog")
  58
  59
  60class Expression(metaclass=_Expression):
  61    """
  62    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  63    context, such as its child expressions, their names (arg keys), and whether a given child expression
  64    is optional or not.
  65
  66    Attributes:
  67        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  68            and representing expressions as strings.
  69        arg_types: determines what arguments (child nodes) are supported by an expression. It
  70            maps arg keys to booleans that indicate whether the corresponding args are optional.
  71        parent: a reference to the parent expression (or None, in case of root expressions).
  72        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  73            uses to refer to it.
  74        comments: a list of comments that are associated with a given expression. This is used in
  75            order to preserve comments when transpiling SQL code.
  76        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  77            optimizer, in order to enable some transformations that require type information.
  78        meta: a dictionary that can be used to store useful metadata for a given expression.
  79
  80    Example:
  81        >>> class Foo(Expression):
  82        ...     arg_types = {"this": True, "expression": False}
  83
  84        The above definition informs us that Foo is an Expression that requires an argument called
  85        "this" and may also optionally receive an argument called "expression".
  86
  87    Args:
  88        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
  89    """
  90
  91    key = "expression"
  92    arg_types = {"this": True}
  93    __slots__ = ("args", "parent", "arg_key", "comments", "_type", "_meta", "_hash")
  94
  95    def __init__(self, **args: t.Any):
  96        self.args: t.Dict[str, t.Any] = args
  97        self.parent: t.Optional[Expression] = None
  98        self.arg_key: t.Optional[str] = None
  99        self.comments: t.Optional[t.List[str]] = None
 100        self._type: t.Optional[DataType] = None
 101        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 102        self._hash: t.Optional[int] = None
 103
 104        for arg_key, value in self.args.items():
 105            self._set_parent(arg_key, value)
 106
 107    def __eq__(self, other) -> bool:
 108        return type(self) is type(other) and hash(self) == hash(other)
 109
 110    @property
 111    def hashable_args(self) -> t.Any:
 112        return frozenset(
 113            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 114            for k, v in self.args.items()
 115            if not (v is None or v is False or (type(v) is list and not v))
 116        )
 117
 118    def __hash__(self) -> int:
 119        if self._hash is not None:
 120            return self._hash
 121
 122        return hash((self.__class__, self.hashable_args))
 123
 124    @property
 125    def this(self) -> t.Any:
 126        """
 127        Retrieves the argument with key "this".
 128        """
 129        return self.args.get("this")
 130
 131    @property
 132    def expression(self) -> t.Any:
 133        """
 134        Retrieves the argument with key "expression".
 135        """
 136        return self.args.get("expression")
 137
 138    @property
 139    def expressions(self) -> t.List[t.Any]:
 140        """
 141        Retrieves the argument with key "expressions".
 142        """
 143        return self.args.get("expressions") or []
 144
 145    def text(self, key) -> str:
 146        """
 147        Returns a textual representation of the argument corresponding to "key". This can only be used
 148        for args that are strings or leaf Expression instances, such as identifiers and literals.
 149        """
 150        field = self.args.get(key)
 151        if isinstance(field, str):
 152            return field
 153        if isinstance(field, (Identifier, Literal, Var)):
 154            return field.this
 155        if isinstance(field, (Star, Null)):
 156            return field.name
 157        return ""
 158
 159    @property
 160    def is_string(self) -> bool:
 161        """
 162        Checks whether a Literal expression is a string.
 163        """
 164        return isinstance(self, Literal) and self.args["is_string"]
 165
 166    @property
 167    def is_number(self) -> bool:
 168        """
 169        Checks whether a Literal expression is a number.
 170        """
 171        return isinstance(self, Literal) and not self.args["is_string"]
 172
 173    @property
 174    def is_int(self) -> bool:
 175        """
 176        Checks whether a Literal expression is an integer.
 177        """
 178        if self.is_number:
 179            try:
 180                int(self.name)
 181                return True
 182            except ValueError:
 183                pass
 184        return False
 185
 186    @property
 187    def is_star(self) -> bool:
 188        """Checks whether an expression is a star."""
 189        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 190
 191    @property
 192    def alias(self) -> str:
 193        """
 194        Returns the alias of the expression, or an empty string if it's not aliased.
 195        """
 196        if isinstance(self.args.get("alias"), TableAlias):
 197            return self.args["alias"].name
 198        return self.text("alias")
 199
 200    @property
 201    def alias_column_names(self) -> t.List[str]:
 202        table_alias = self.args.get("alias")
 203        if not table_alias:
 204            return []
 205        return [c.name for c in table_alias.args.get("columns") or []]
 206
 207    @property
 208    def name(self) -> str:
 209        return self.text("this")
 210
 211    @property
 212    def alias_or_name(self) -> str:
 213        return self.alias or self.name
 214
 215    @property
 216    def output_name(self) -> str:
 217        """
 218        Name of the output column if this expression is a selection.
 219
 220        If the Expression has no output name, an empty string is returned.
 221
 222        Example:
 223            >>> from sqlglot import parse_one
 224            >>> parse_one("SELECT a").expressions[0].output_name
 225            'a'
 226            >>> parse_one("SELECT b AS c").expressions[0].output_name
 227            'c'
 228            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 229            ''
 230        """
 231        return ""
 232
 233    @property
 234    def type(self) -> t.Optional[DataType]:
 235        return self._type
 236
 237    @type.setter
 238    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 239        if dtype and not isinstance(dtype, DataType):
 240            dtype = DataType.build(dtype)
 241        self._type = dtype  # type: ignore
 242
 243    def is_type(self, *dtypes) -> bool:
 244        return self.type is not None and self.type.is_type(*dtypes)
 245
 246    def is_leaf(self) -> bool:
 247        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 248
 249    @property
 250    def meta(self) -> t.Dict[str, t.Any]:
 251        if self._meta is None:
 252            self._meta = {}
 253        return self._meta
 254
 255    def __deepcopy__(self, memo):
 256        copy = self.__class__(**deepcopy(self.args))
 257        if self.comments is not None:
 258            copy.comments = deepcopy(self.comments)
 259
 260        if self._type is not None:
 261            copy._type = self._type.copy()
 262
 263        if self._meta is not None:
 264            copy._meta = deepcopy(self._meta)
 265
 266        return copy
 267
 268    def copy(self):
 269        """
 270        Returns a deep copy of the expression.
 271        """
 272        new = deepcopy(self)
 273        new.parent = self.parent
 274        return new
 275
 276    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
 277        if self.comments is None:
 278            self.comments = []
 279        if comments:
 280            for comment in comments:
 281                _, *meta = comment.split(SQLGLOT_META)
 282                if meta:
 283                    for kv in "".join(meta).split(","):
 284                        k, *v = kv.split("=")
 285                        value = v[0].strip() if v else True
 286                        self.meta[k.strip()] = value
 287                self.comments.append(comment)
 288
 289    def append(self, arg_key: str, value: t.Any) -> None:
 290        """
 291        Appends value to arg_key if it's a list or sets it as a new list.
 292
 293        Args:
 294            arg_key (str): name of the list expression arg
 295            value (Any): value to append to the list
 296        """
 297        if not isinstance(self.args.get(arg_key), list):
 298            self.args[arg_key] = []
 299        self.args[arg_key].append(value)
 300        self._set_parent(arg_key, value)
 301
 302    def set(self, arg_key: str, value: t.Any) -> None:
 303        """
 304        Sets arg_key to value.
 305
 306        Args:
 307            arg_key: name of the expression arg.
 308            value: value to set the arg to.
 309        """
 310        if value is None:
 311            self.args.pop(arg_key, None)
 312            return
 313
 314        self.args[arg_key] = value
 315        self._set_parent(arg_key, value)
 316
 317    def _set_parent(self, arg_key: str, value: t.Any) -> None:
 318        if hasattr(value, "parent"):
 319            value.parent = self
 320            value.arg_key = arg_key
 321        elif type(value) is list:
 322            for v in value:
 323                if hasattr(v, "parent"):
 324                    v.parent = self
 325                    v.arg_key = arg_key
 326
 327    @property
 328    def depth(self) -> int:
 329        """
 330        Returns the depth of this tree.
 331        """
 332        if self.parent:
 333            return self.parent.depth + 1
 334        return 0
 335
 336    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
 337        """Yields the key and expression for all arguments, exploding list args."""
 338        for k, vs in self.args.items():
 339            if type(vs) is list:
 340                for v in vs:
 341                    if hasattr(v, "parent"):
 342                        yield k, v
 343            else:
 344                if hasattr(vs, "parent"):
 345                    yield k, vs
 346
 347    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 348        """
 349        Returns the first node in this tree which matches at least one of
 350        the specified types.
 351
 352        Args:
 353            expression_types: the expression type(s) to match.
 354            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 355
 356        Returns:
 357            The node which matches the criteria or None if no such node was found.
 358        """
 359        return next(self.find_all(*expression_types, bfs=bfs), None)
 360
 361    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 362        """
 363        Returns a generator object which visits all nodes in this tree and only
 364        yields those that match at least one of the specified expression types.
 365
 366        Args:
 367            expression_types: the expression type(s) to match.
 368            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 369
 370        Returns:
 371            The generator object.
 372        """
 373        for expression, *_ in self.walk(bfs=bfs):
 374            if isinstance(expression, expression_types):
 375                yield expression
 376
 377    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 378        """
 379        Returns a nearest parent matching expression_types.
 380
 381        Args:
 382            expression_types: the expression type(s) to match.
 383
 384        Returns:
 385            The parent node.
 386        """
 387        ancestor = self.parent
 388        while ancestor and not isinstance(ancestor, expression_types):
 389            ancestor = ancestor.parent
 390        return ancestor  # type: ignore
 391
 392    @property
 393    def parent_select(self) -> t.Optional[Select]:
 394        """
 395        Returns the parent select statement.
 396        """
 397        return self.find_ancestor(Select)
 398
 399    @property
 400    def same_parent(self) -> bool:
 401        """Returns if the parent is the same class as itself."""
 402        return type(self.parent) is self.__class__
 403
 404    def root(self) -> Expression:
 405        """
 406        Returns the root expression of this tree.
 407        """
 408        expression = self
 409        while expression.parent:
 410            expression = expression.parent
 411        return expression
 412
 413    def walk(self, bfs=True, prune=None):
 414        """
 415        Returns a generator object which visits all nodes in this tree.
 416
 417        Args:
 418            bfs (bool): if set to True the BFS traversal order will be applied,
 419                otherwise the DFS traversal will be used instead.
 420            prune ((node, parent, arg_key) -> bool): callable that returns True if
 421                the generator should stop traversing this branch of the tree.
 422
 423        Returns:
 424            the generator object.
 425        """
 426        if bfs:
 427            yield from self.bfs(prune=prune)
 428        else:
 429            yield from self.dfs(prune=prune)
 430
 431    def dfs(self, parent=None, key=None, prune=None):
 432        """
 433        Returns a generator object which visits all nodes in this tree in
 434        the DFS (Depth-first) order.
 435
 436        Returns:
 437            The generator object.
 438        """
 439        parent = parent or self.parent
 440        yield self, parent, key
 441        if prune and prune(self, parent, key):
 442            return
 443
 444        for k, v in self.iter_expressions():
 445            yield from v.dfs(self, k, prune)
 446
 447    def bfs(self, prune=None):
 448        """
 449        Returns a generator object which visits all nodes in this tree in
 450        the BFS (Breadth-first) order.
 451
 452        Returns:
 453            The generator object.
 454        """
 455        queue = deque([(self, self.parent, None)])
 456
 457        while queue:
 458            item, parent, key = queue.popleft()
 459
 460            yield item, parent, key
 461            if prune and prune(item, parent, key):
 462                continue
 463
 464            for k, v in item.iter_expressions():
 465                queue.append((v, item, k))
 466
 467    def unnest(self):
 468        """
 469        Returns the first non parenthesis child or self.
 470        """
 471        expression = self
 472        while type(expression) is Paren:
 473            expression = expression.this
 474        return expression
 475
 476    def unalias(self):
 477        """
 478        Returns the inner expression if this is an Alias.
 479        """
 480        if isinstance(self, Alias):
 481            return self.this
 482        return self
 483
 484    def unnest_operands(self):
 485        """
 486        Returns unnested operands as a tuple.
 487        """
 488        return tuple(arg.unnest() for _, arg in self.iter_expressions())
 489
 490    def flatten(self, unnest=True):
 491        """
 492        Returns a generator which yields child nodes whose parents are the same class.
 493
 494        A AND B AND C -> [A, B, C]
 495        """
 496        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
 497            if not type(node) is self.__class__:
 498                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 499
 500    def __str__(self) -> str:
 501        return self.sql()
 502
 503    def __repr__(self) -> str:
 504        return _to_s(self)
 505
 506    def to_s(self) -> str:
 507        """
 508        Same as __repr__, but includes additional information which can be useful
 509        for debugging, like empty or missing args and the AST nodes' object IDs.
 510        """
 511        return _to_s(self, verbose=True)
 512
 513    def sql(self, dialect: DialectType = None, **opts) -> str:
 514        """
 515        Returns SQL string representation of this tree.
 516
 517        Args:
 518            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 519            opts: other `sqlglot.generator.Generator` options.
 520
 521        Returns:
 522            The SQL string.
 523        """
 524        from sqlglot.dialects import Dialect
 525
 526        return Dialect.get_or_raise(dialect).generate(self, **opts)
 527
 528    def transform(self, fun, *args, copy=True, **kwargs):
 529        """
 530        Recursively visits all tree nodes (excluding already transformed ones)
 531        and applies the given transformation function to each node.
 532
 533        Args:
 534            fun (function): a function which takes a node as an argument and returns a
 535                new transformed node or the same node without modifications. If the function
 536                returns None, then the corresponding node will be removed from the syntax tree.
 537            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
 538                modified in place.
 539
 540        Returns:
 541            The transformed tree.
 542        """
 543        node = self.copy() if copy else self
 544        new_node = fun(node, *args, **kwargs)
 545
 546        if new_node is None or not isinstance(new_node, Expression):
 547            return new_node
 548        if new_node is not node:
 549            new_node.parent = node.parent
 550            return new_node
 551
 552        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
 553        return new_node
 554
 555    @t.overload
 556    def replace(self, expression: E) -> E: ...
 557
 558    @t.overload
 559    def replace(self, expression: None) -> None: ...
 560
 561    def replace(self, expression):
 562        """
 563        Swap out this expression with a new expression.
 564
 565        For example::
 566
 567            >>> tree = Select().select("x").from_("tbl")
 568            >>> tree.find(Column).replace(column("y"))
 569            Column(
 570              this=Identifier(this=y, quoted=False))
 571            >>> tree.sql()
 572            'SELECT y FROM tbl'
 573
 574        Args:
 575            expression: new node
 576
 577        Returns:
 578            The new expression or expressions.
 579        """
 580        if not self.parent:
 581            return expression
 582
 583        parent = self.parent
 584        self.parent = None
 585
 586        replace_children(parent, lambda child: expression if child is self else child)
 587        return expression
 588
 589    def pop(self: E) -> E:
 590        """
 591        Remove this expression from its AST.
 592
 593        Returns:
 594            The popped expression.
 595        """
 596        self.replace(None)
 597        return self
 598
 599    def assert_is(self, type_: t.Type[E]) -> E:
 600        """
 601        Assert that this `Expression` is an instance of `type_`.
 602
 603        If it is NOT an instance of `type_`, this raises an assertion error.
 604        Otherwise, this returns this expression.
 605
 606        Examples:
 607            This is useful for type security in chained expressions:
 608
 609            >>> import sqlglot
 610            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 611            'SELECT x, z FROM y'
 612        """
 613        assert isinstance(self, type_)
 614        return self
 615
 616    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 617        """
 618        Checks if this expression is valid (e.g. all mandatory args are set).
 619
 620        Args:
 621            args: a sequence of values that were used to instantiate a Func expression. This is used
 622                to check that the provided arguments don't exceed the function argument limit.
 623
 624        Returns:
 625            A list of error messages for all possible errors that were found.
 626        """
 627        errors: t.List[str] = []
 628
 629        for k in self.args:
 630            if k not in self.arg_types:
 631                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 632        for k, mandatory in self.arg_types.items():
 633            v = self.args.get(k)
 634            if mandatory and (v is None or (isinstance(v, list) and not v)):
 635                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 636
 637        if (
 638            args
 639            and isinstance(self, Func)
 640            and len(args) > len(self.arg_types)
 641            and not self.is_var_len_args
 642        ):
 643            errors.append(
 644                f"The number of provided arguments ({len(args)}) is greater than "
 645                f"the maximum number of supported arguments ({len(self.arg_types)})"
 646            )
 647
 648        return errors
 649
 650    def dump(self):
 651        """
 652        Dump this Expression to a JSON-serializable dict.
 653        """
 654        from sqlglot.serde import dump
 655
 656        return dump(self)
 657
 658    @classmethod
 659    def load(cls, obj):
 660        """
 661        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 662        """
 663        from sqlglot.serde import load
 664
 665        return load(obj)
 666
 667    def and_(
 668        self,
 669        *expressions: t.Optional[ExpOrStr],
 670        dialect: DialectType = None,
 671        copy: bool = True,
 672        **opts,
 673    ) -> Condition:
 674        """
 675        AND this condition with one or multiple expressions.
 676
 677        Example:
 678            >>> condition("x=1").and_("y=1").sql()
 679            'x = 1 AND y = 1'
 680
 681        Args:
 682            *expressions: the SQL code strings to parse.
 683                If an `Expression` instance is passed, it will be used as-is.
 684            dialect: the dialect used to parse the input expression.
 685            copy: whether or not to copy the involved expressions (only applies to Expressions).
 686            opts: other options to use to parse the input expressions.
 687
 688        Returns:
 689            The new And condition.
 690        """
 691        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)
 692
 693    def or_(
 694        self,
 695        *expressions: t.Optional[ExpOrStr],
 696        dialect: DialectType = None,
 697        copy: bool = True,
 698        **opts,
 699    ) -> Condition:
 700        """
 701        OR this condition with one or multiple expressions.
 702
 703        Example:
 704            >>> condition("x=1").or_("y=1").sql()
 705            'x = 1 OR y = 1'
 706
 707        Args:
 708            *expressions: the SQL code strings to parse.
 709                If an `Expression` instance is passed, it will be used as-is.
 710            dialect: the dialect used to parse the input expression.
 711            copy: whether or not to copy the involved expressions (only applies to Expressions).
 712            opts: other options to use to parse the input expressions.
 713
 714        Returns:
 715            The new Or condition.
 716        """
 717        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)
 718
 719    def not_(self, copy: bool = True):
 720        """
 721        Wrap this condition with NOT.
 722
 723        Example:
 724            >>> condition("x=1").not_().sql()
 725            'NOT x = 1'
 726
 727        Args:
 728            copy: whether or not to copy this object.
 729
 730        Returns:
 731            The new Not instance.
 732        """
 733        return not_(self, copy=copy)
 734
 735    def as_(
 736        self,
 737        alias: str | Identifier,
 738        quoted: t.Optional[bool] = None,
 739        dialect: DialectType = None,
 740        copy: bool = True,
 741        **opts,
 742    ) -> Alias:
 743        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 744
 745    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 746        this = self.copy()
 747        other = convert(other, copy=True)
 748        if not isinstance(this, klass) and not isinstance(other, klass):
 749            this = _wrap(this, Binary)
 750            other = _wrap(other, Binary)
 751        if reverse:
 752            return klass(this=other, expression=this)
 753        return klass(this=this, expression=other)
 754
 755    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 756        return Bracket(
 757            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 758        )
 759
 760    def __iter__(self) -> t.Iterator:
 761        if "expressions" in self.arg_types:
 762            return iter(self.args.get("expressions") or [])
 763        # We define this because __getitem__ converts Expression into an iterable, which is
 764        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 765        # See: https://peps.python.org/pep-0234/
 766        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 767
 768    def isin(
 769        self,
 770        *expressions: t.Any,
 771        query: t.Optional[ExpOrStr] = None,
 772        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 773        copy: bool = True,
 774        **opts,
 775    ) -> In:
 776        return In(
 777            this=maybe_copy(self, copy),
 778            expressions=[convert(e, copy=copy) for e in expressions],
 779            query=maybe_parse(query, copy=copy, **opts) if query else None,
 780            unnest=(
 781                Unnest(
 782                    expressions=[
 783                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 784                        for e in ensure_list(unnest)
 785                    ]
 786                )
 787                if unnest
 788                else None
 789            ),
 790        )
 791
 792    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 793        return Between(
 794            this=maybe_copy(self, copy),
 795            low=convert(low, copy=copy, **opts),
 796            high=convert(high, copy=copy, **opts),
 797        )
 798
 799    def is_(self, other: ExpOrStr) -> Is:
 800        return self._binop(Is, other)
 801
 802    def like(self, other: ExpOrStr) -> Like:
 803        return self._binop(Like, other)
 804
 805    def ilike(self, other: ExpOrStr) -> ILike:
 806        return self._binop(ILike, other)
 807
 808    def eq(self, other: t.Any) -> EQ:
 809        return self._binop(EQ, other)
 810
 811    def neq(self, other: t.Any) -> NEQ:
 812        return self._binop(NEQ, other)
 813
 814    def rlike(self, other: ExpOrStr) -> RegexpLike:
 815        return self._binop(RegexpLike, other)
 816
 817    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 818        div = self._binop(Div, other)
 819        div.args["typed"] = typed
 820        div.args["safe"] = safe
 821        return div
 822
 823    def desc(self, nulls_first: bool = False) -> Ordered:
 824        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 825
 826    def __lt__(self, other: t.Any) -> LT:
 827        return self._binop(LT, other)
 828
 829    def __le__(self, other: t.Any) -> LTE:
 830        return self._binop(LTE, other)
 831
 832    def __gt__(self, other: t.Any) -> GT:
 833        return self._binop(GT, other)
 834
 835    def __ge__(self, other: t.Any) -> GTE:
 836        return self._binop(GTE, other)
 837
 838    def __add__(self, other: t.Any) -> Add:
 839        return self._binop(Add, other)
 840
 841    def __radd__(self, other: t.Any) -> Add:
 842        return self._binop(Add, other, reverse=True)
 843
 844    def __sub__(self, other: t.Any) -> Sub:
 845        return self._binop(Sub, other)
 846
 847    def __rsub__(self, other: t.Any) -> Sub:
 848        return self._binop(Sub, other, reverse=True)
 849
 850    def __mul__(self, other: t.Any) -> Mul:
 851        return self._binop(Mul, other)
 852
 853    def __rmul__(self, other: t.Any) -> Mul:
 854        return self._binop(Mul, other, reverse=True)
 855
 856    def __truediv__(self, other: t.Any) -> Div:
 857        return self._binop(Div, other)
 858
 859    def __rtruediv__(self, other: t.Any) -> Div:
 860        return self._binop(Div, other, reverse=True)
 861
 862    def __floordiv__(self, other: t.Any) -> IntDiv:
 863        return self._binop(IntDiv, other)
 864
 865    def __rfloordiv__(self, other: t.Any) -> IntDiv:
 866        return self._binop(IntDiv, other, reverse=True)
 867
 868    def __mod__(self, other: t.Any) -> Mod:
 869        return self._binop(Mod, other)
 870
 871    def __rmod__(self, other: t.Any) -> Mod:
 872        return self._binop(Mod, other, reverse=True)
 873
 874    def __pow__(self, other: t.Any) -> Pow:
 875        return self._binop(Pow, other)
 876
 877    def __rpow__(self, other: t.Any) -> Pow:
 878        return self._binop(Pow, other, reverse=True)
 879
 880    def __and__(self, other: t.Any) -> And:
 881        return self._binop(And, other)
 882
 883    def __rand__(self, other: t.Any) -> And:
 884        return self._binop(And, other, reverse=True)
 885
 886    def __or__(self, other: t.Any) -> Or:
 887        return self._binop(Or, other)
 888
 889    def __ror__(self, other: t.Any) -> Or:
 890        return self._binop(Or, other, reverse=True)
 891
 892    def __neg__(self) -> Neg:
 893        return Neg(this=_wrap(self.copy(), Binary))
 894
 895    def __invert__(self) -> Not:
 896        return not_(self.copy())
 897
 898
 899IntoType = t.Union[
 900    str,
 901    t.Type[Expression],
 902    t.Collection[t.Union[str, t.Type[Expression]]],
 903]
 904ExpOrStr = t.Union[str, Expression]
 905
 906
 907class Condition(Expression):
 908    """Logical conditions like x AND y, or simply x"""
 909
 910
 911class Predicate(Condition):
 912    """Relationships like x = y, x > 1, x >= y."""
 913
 914
 915class DerivedTable(Expression):
 916    @property
 917    def selects(self) -> t.List[Expression]:
 918        return self.this.selects if isinstance(self.this, Subqueryable) else []
 919
 920    @property
 921    def named_selects(self) -> t.List[str]:
 922        return [select.output_name for select in self.selects]
 923
 924
 925class Unionable(Expression):
 926    def union(
 927        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
 928    ) -> Union:
 929        """
 930        Builds a UNION expression.
 931
 932        Example:
 933            >>> import sqlglot
 934            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
 935            'SELECT * FROM foo UNION SELECT * FROM bla'
 936
 937        Args:
 938            expression: the SQL code string.
 939                If an `Expression` instance is passed, it will be used as-is.
 940            distinct: set the DISTINCT flag if and only if this is true.
 941            dialect: the dialect used to parse the input expression.
 942            opts: other options to use to parse the input expressions.
 943
 944        Returns:
 945            The new Union expression.
 946        """
 947        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
 948
 949    def intersect(
 950        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
 951    ) -> Unionable:
 952        """
 953        Builds an INTERSECT expression.
 954
 955        Example:
 956            >>> import sqlglot
 957            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
 958            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
 959
 960        Args:
 961            expression: the SQL code string.
 962                If an `Expression` instance is passed, it will be used as-is.
 963            distinct: set the DISTINCT flag if and only if this is true.
 964            dialect: the dialect used to parse the input expression.
 965            opts: other options to use to parse the input expressions.
 966
 967        Returns:
 968            The new Intersect expression.
 969        """
 970        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
 971
 972    def except_(
 973        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
 974    ) -> Unionable:
 975        """
 976        Builds an EXCEPT expression.
 977
 978        Example:
 979            >>> import sqlglot
 980            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
 981            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
 982
 983        Args:
 984            expression: the SQL code string.
 985                If an `Expression` instance is passed, it will be used as-is.
 986            distinct: set the DISTINCT flag if and only if this is true.
 987            dialect: the dialect used to parse the input expression.
 988            opts: other options to use to parse the input expressions.
 989
 990        Returns:
 991            The new Except expression.
 992        """
 993        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
 994
 995
 996class UDTF(DerivedTable, Unionable):
 997    @property
 998    def selects(self) -> t.List[Expression]:
 999        alias = self.args.get("alias")
1000        return alias.columns if alias else []
1001
1002
1003class Cache(Expression):
1004    arg_types = {
1005        "this": True,
1006        "lazy": False,
1007        "options": False,
1008        "expression": False,
1009    }
1010
1011
1012class Uncache(Expression):
1013    arg_types = {"this": True, "exists": False}
1014
1015
1016class Refresh(Expression):
1017    pass
1018
1019
1020class DDL(Expression):
1021    @property
1022    def ctes(self):
1023        with_ = self.args.get("with")
1024        if not with_:
1025            return []
1026        return with_.expressions
1027
1028    @property
1029    def named_selects(self) -> t.List[str]:
1030        if isinstance(self.expression, Subqueryable):
1031            return self.expression.named_selects
1032        return []
1033
1034    @property
1035    def selects(self) -> t.List[Expression]:
1036        if isinstance(self.expression, Subqueryable):
1037            return self.expression.selects
1038        return []
1039
1040
1041class DML(Expression):
1042    def returning(
1043        self,
1044        expression: ExpOrStr,
1045        dialect: DialectType = None,
1046        copy: bool = True,
1047        **opts,
1048    ) -> DML:
1049        """
1050        Set the RETURNING expression. Not supported by all dialects.
1051
1052        Example:
1053            >>> delete("tbl").returning("*", dialect="postgres").sql()
1054            'DELETE FROM tbl RETURNING *'
1055
1056        Args:
1057            expression: the SQL code strings to parse.
1058                If an `Expression` instance is passed, it will be used as-is.
1059            dialect: the dialect used to parse the input expressions.
1060            copy: if `False`, modify this expression instance in-place.
1061            opts: other options to use to parse the input expressions.
1062
1063        Returns:
1064            Delete: the modified expression.
1065        """
1066        return _apply_builder(
1067            expression=expression,
1068            instance=self,
1069            arg="returning",
1070            prefix="RETURNING",
1071            dialect=dialect,
1072            copy=copy,
1073            into=Returning,
1074            **opts,
1075        )
1076
1077
1078class Create(DDL):
1079    arg_types = {
1080        "with": False,
1081        "this": True,
1082        "kind": True,
1083        "expression": False,
1084        "exists": False,
1085        "properties": False,
1086        "replace": False,
1087        "unique": False,
1088        "indexes": False,
1089        "no_schema_binding": False,
1090        "begin": False,
1091        "end": False,
1092        "clone": False,
1093    }
1094
1095
1096# https://docs.snowflake.com/en/sql-reference/sql/create-clone
1097# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_clone_statement
1098# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_copy
1099class Clone(Expression):
1100    arg_types = {"this": True, "shallow": False, "copy": False}
1101
1102
1103class Describe(Expression):
1104    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
1105
1106
1107class Kill(Expression):
1108    arg_types = {"this": True, "kind": False}
1109
1110
1111class Pragma(Expression):
1112    pass
1113
1114
1115class Set(Expression):
1116    arg_types = {"expressions": False, "unset": False, "tag": False}
1117
1118
1119class Heredoc(Expression):
1120    arg_types = {"this": True, "tag": False}
1121
1122
1123class SetItem(Expression):
1124    arg_types = {
1125        "this": False,
1126        "expressions": False,
1127        "kind": False,
1128        "collate": False,  # MySQL SET NAMES statement
1129        "global": False,
1130    }
1131
1132
1133class Show(Expression):
1134    arg_types = {
1135        "this": True,
1136        "terse": False,
1137        "target": False,
1138        "offset": False,
1139        "starts_with": False,
1140        "limit": False,
1141        "from": False,
1142        "like": False,
1143        "where": False,
1144        "db": False,
1145        "scope": False,
1146        "scope_kind": False,
1147        "full": False,
1148        "mutex": False,
1149        "query": False,
1150        "channel": False,
1151        "global": False,
1152        "log": False,
1153        "position": False,
1154        "types": False,
1155    }
1156
1157
1158class UserDefinedFunction(Expression):
1159    arg_types = {"this": True, "expressions": False, "wrapped": False}
1160
1161
1162class CharacterSet(Expression):
1163    arg_types = {"this": True, "default": False}
1164
1165
1166class With(Expression):
1167    arg_types = {"expressions": True, "recursive": False}
1168
1169    @property
1170    def recursive(self) -> bool:
1171        return bool(self.args.get("recursive"))
1172
1173
1174class WithinGroup(Expression):
1175    arg_types = {"this": True, "expression": False}
1176
1177
1178# clickhouse supports scalar ctes
1179# https://clickhouse.com/docs/en/sql-reference/statements/select/with
1180class CTE(DerivedTable):
1181    arg_types = {"this": True, "alias": True, "scalar": False}
1182
1183
1184class TableAlias(Expression):
1185    arg_types = {"this": False, "columns": False}
1186
1187    @property
1188    def columns(self):
1189        return self.args.get("columns") or []
1190
1191
1192class BitString(Condition):
1193    pass
1194
1195
1196class HexString(Condition):
1197    pass
1198
1199
1200class ByteString(Condition):
1201    pass
1202
1203
1204class RawString(Condition):
1205    pass
1206
1207
1208class UnicodeString(Condition):
1209    arg_types = {"this": True, "escape": False}
1210
1211
1212class Column(Condition):
1213    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1214
1215    @property
1216    def table(self) -> str:
1217        return self.text("table")
1218
1219    @property
1220    def db(self) -> str:
1221        return self.text("db")
1222
1223    @property
1224    def catalog(self) -> str:
1225        return self.text("catalog")
1226
1227    @property
1228    def output_name(self) -> str:
1229        return self.name
1230
1231    @property
1232    def parts(self) -> t.List[Identifier]:
1233        """Return the parts of a column in order catalog, db, table, name."""
1234        return [
1235            t.cast(Identifier, self.args[part])
1236            for part in ("catalog", "db", "table", "this")
1237            if self.args.get(part)
1238        ]
1239
1240    def to_dot(self) -> Dot | Identifier:
1241        """Converts the column into a dot expression."""
1242        parts = self.parts
1243        parent = self.parent
1244
1245        while parent:
1246            if isinstance(parent, Dot):
1247                parts.append(parent.expression)
1248            parent = parent.parent
1249
1250        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
1251
1252
1253class ColumnPosition(Expression):
1254    arg_types = {"this": False, "position": True}
1255
1256
1257class ColumnDef(Expression):
1258    arg_types = {
1259        "this": True,
1260        "kind": False,
1261        "constraints": False,
1262        "exists": False,
1263        "position": False,
1264    }
1265
1266    @property
1267    def constraints(self) -> t.List[ColumnConstraint]:
1268        return self.args.get("constraints") or []
1269
1270
1271class AlterColumn(Expression):
1272    arg_types = {
1273        "this": True,
1274        "dtype": False,
1275        "collate": False,
1276        "using": False,
1277        "default": False,
1278        "drop": False,
1279        "comment": False,
1280    }
1281
1282
1283class RenameColumn(Expression):
1284    arg_types = {"this": True, "to": True, "exists": False}
1285
1286
1287class RenameTable(Expression):
1288    pass
1289
1290
1291class SwapTable(Expression):
1292    pass
1293
1294
1295class Comment(Expression):
1296    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
1297
1298
1299class Comprehension(Expression):
1300    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
1301
1302
1303# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1304class MergeTreeTTLAction(Expression):
1305    arg_types = {
1306        "this": True,
1307        "delete": False,
1308        "recompress": False,
1309        "to_disk": False,
1310        "to_volume": False,
1311    }
1312
1313
1314# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1315class MergeTreeTTL(Expression):
1316    arg_types = {
1317        "expressions": True,
1318        "where": False,
1319        "group": False,
1320        "aggregates": False,
1321    }
1322
1323
1324# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1325class IndexConstraintOption(Expression):
1326    arg_types = {
1327        "key_block_size": False,
1328        "using": False,
1329        "parser": False,
1330        "comment": False,
1331        "visible": False,
1332        "engine_attr": False,
1333        "secondary_engine_attr": False,
1334    }
1335
1336
1337class ColumnConstraint(Expression):
1338    arg_types = {"this": False, "kind": True}
1339
1340    @property
1341    def kind(self) -> ColumnConstraintKind:
1342        return self.args["kind"]
1343
1344
1345class ColumnConstraintKind(Expression):
1346    pass
1347
1348
1349class AutoIncrementColumnConstraint(ColumnConstraintKind):
1350    pass
1351
1352
1353class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1354    arg_types = {"this": True, "expression": True}
1355
1356
1357class CaseSpecificColumnConstraint(ColumnConstraintKind):
1358    arg_types = {"not_": True}
1359
1360
1361class CharacterSetColumnConstraint(ColumnConstraintKind):
1362    arg_types = {"this": True}
1363
1364
1365class CheckColumnConstraint(ColumnConstraintKind):
1366    pass
1367
1368
1369class ClusteredColumnConstraint(ColumnConstraintKind):
1370    pass
1371
1372
1373class CollateColumnConstraint(ColumnConstraintKind):
1374    pass
1375
1376
1377class CommentColumnConstraint(ColumnConstraintKind):
1378    pass
1379
1380
1381class CompressColumnConstraint(ColumnConstraintKind):
1382    pass
1383
1384
1385class DateFormatColumnConstraint(ColumnConstraintKind):
1386    arg_types = {"this": True}
1387
1388
1389class DefaultColumnConstraint(ColumnConstraintKind):
1390    pass
1391
1392
1393class EncodeColumnConstraint(ColumnConstraintKind):
1394    pass
1395
1396
1397class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1398    # this: True -> ALWAYS, this: False -> BY DEFAULT
1399    arg_types = {
1400        "this": False,
1401        "expression": False,
1402        "on_null": False,
1403        "start": False,
1404        "increment": False,
1405        "minvalue": False,
1406        "maxvalue": False,
1407        "cycle": False,
1408    }
1409
1410
1411class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1412    arg_types = {"start": False, "hidden": False}
1413
1414
1415# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1416class IndexColumnConstraint(ColumnConstraintKind):
1417    arg_types = {
1418        "this": False,
1419        "schema": True,
1420        "kind": False,
1421        "index_type": False,
1422        "options": False,
1423    }
1424
1425
1426class InlineLengthColumnConstraint(ColumnConstraintKind):
1427    pass
1428
1429
1430class NonClusteredColumnConstraint(ColumnConstraintKind):
1431    pass
1432
1433
1434class NotForReplicationColumnConstraint(ColumnConstraintKind):
1435    arg_types = {}
1436
1437
1438class NotNullColumnConstraint(ColumnConstraintKind):
1439    arg_types = {"allow_null": False}
1440
1441
1442# https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
1443class OnUpdateColumnConstraint(ColumnConstraintKind):
1444    pass
1445
1446
1447# https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
1448class TransformColumnConstraint(ColumnConstraintKind):
1449    pass
1450
1451
1452class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1453    arg_types = {"desc": False}
1454
1455
1456class TitleColumnConstraint(ColumnConstraintKind):
1457    pass
1458
1459
1460class UniqueColumnConstraint(ColumnConstraintKind):
1461    arg_types = {"this": False, "index_type": False}
1462
1463
1464class UppercaseColumnConstraint(ColumnConstraintKind):
1465    arg_types: t.Dict[str, t.Any] = {}
1466
1467
1468class PathColumnConstraint(ColumnConstraintKind):
1469    pass
1470
1471
1472# computed column expression
1473# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver16
1474class ComputedColumnConstraint(ColumnConstraintKind):
1475    arg_types = {"this": True, "persisted": False, "not_null": False}
1476
1477
1478class Constraint(Expression):
1479    arg_types = {"this": True, "expressions": True}
1480
1481
1482class Delete(DML):
1483    arg_types = {
1484        "with": False,
1485        "this": False,
1486        "using": False,
1487        "where": False,
1488        "returning": False,
1489        "limit": False,
1490        "tables": False,  # Multiple-Table Syntax (MySQL)
1491    }
1492
1493    def delete(
1494        self,
1495        table: ExpOrStr,
1496        dialect: DialectType = None,
1497        copy: bool = True,
1498        **opts,
1499    ) -> Delete:
1500        """
1501        Create a DELETE expression or replace the table on an existing DELETE expression.
1502
1503        Example:
1504            >>> delete("tbl").sql()
1505            'DELETE FROM tbl'
1506
1507        Args:
1508            table: the table from which to delete.
1509            dialect: the dialect used to parse the input expression.
1510            copy: if `False`, modify this expression instance in-place.
1511            opts: other options to use to parse the input expressions.
1512
1513        Returns:
1514            Delete: the modified expression.
1515        """
1516        return _apply_builder(
1517            expression=table,
1518            instance=self,
1519            arg="this",
1520            dialect=dialect,
1521            into=Table,
1522            copy=copy,
1523            **opts,
1524        )
1525
1526    def where(
1527        self,
1528        *expressions: t.Optional[ExpOrStr],
1529        append: bool = True,
1530        dialect: DialectType = None,
1531        copy: bool = True,
1532        **opts,
1533    ) -> Delete:
1534        """
1535        Append to or set the WHERE expressions.
1536
1537        Example:
1538            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1539            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1540
1541        Args:
1542            *expressions: the SQL code strings to parse.
1543                If an `Expression` instance is passed, it will be used as-is.
1544                Multiple expressions are combined with an AND operator.
1545            append: if `True`, AND the new expressions to any existing expression.
1546                Otherwise, this resets the expression.
1547            dialect: the dialect used to parse the input expressions.
1548            copy: if `False`, modify this expression instance in-place.
1549            opts: other options to use to parse the input expressions.
1550
1551        Returns:
1552            Delete: the modified expression.
1553        """
1554        return _apply_conjunction_builder(
1555            *expressions,
1556            instance=self,
1557            arg="where",
1558            append=append,
1559            into=Where,
1560            dialect=dialect,
1561            copy=copy,
1562            **opts,
1563        )
1564
1565
1566class Drop(Expression):
1567    arg_types = {
1568        "this": False,
1569        "kind": False,
1570        "exists": False,
1571        "temporary": False,
1572        "materialized": False,
1573        "cascade": False,
1574        "constraints": False,
1575        "purge": False,
1576    }
1577
1578
1579class Filter(Expression):
1580    arg_types = {"this": True, "expression": True}
1581
1582
1583class Check(Expression):
1584    pass
1585
1586
1587# https://docs.snowflake.com/en/sql-reference/constructs/connect-by
1588class Connect(Expression):
1589    arg_types = {"start": False, "connect": True}
1590
1591
1592class Prior(Expression):
1593    pass
1594
1595
1596class Directory(Expression):
1597    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1598    arg_types = {"this": True, "local": False, "row_format": False}
1599
1600
1601class ForeignKey(Expression):
1602    arg_types = {
1603        "expressions": True,
1604        "reference": False,
1605        "delete": False,
1606        "update": False,
1607    }
1608
1609
1610class ColumnPrefix(Expression):
1611    arg_types = {"this": True, "expression": True}
1612
1613
1614class PrimaryKey(Expression):
1615    arg_types = {"expressions": True, "options": False}
1616
1617
1618# https://www.postgresql.org/docs/9.1/sql-selectinto.html
1619# https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_INTO.html#r_SELECT_INTO-examples
1620class Into(Expression):
1621    arg_types = {"this": True, "temporary": False, "unlogged": False}
1622
1623
1624class From(Expression):
1625    @property
1626    def name(self) -> str:
1627        return self.this.name
1628
1629    @property
1630    def alias_or_name(self) -> str:
1631        return self.this.alias_or_name
1632
1633
1634class Having(Expression):
1635    pass
1636
1637
1638class Hint(Expression):
1639    arg_types = {"expressions": True}
1640
1641
1642class JoinHint(Expression):
1643    arg_types = {"this": True, "expressions": True}
1644
1645
1646class Identifier(Expression):
1647    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1648
1649    @property
1650    def quoted(self) -> bool:
1651        return bool(self.args.get("quoted"))
1652
1653    @property
1654    def hashable_args(self) -> t.Any:
1655        return (self.this, self.quoted)
1656
1657    @property
1658    def output_name(self) -> str:
1659        return self.name
1660
1661
1662# https://www.postgresql.org/docs/current/indexes-opclass.html
1663class Opclass(Expression):
1664    arg_types = {"this": True, "expression": True}
1665
1666
1667class Index(Expression):
1668    arg_types = {
1669        "this": False,
1670        "table": False,
1671        "using": False,
1672        "where": False,
1673        "columns": False,
1674        "unique": False,
1675        "primary": False,
1676        "amp": False,  # teradata
1677        "include": False,
1678        "partition_by": False,  # teradata
1679        "where": False,  # postgres partial indexes
1680    }
1681
1682
1683class Insert(DDL, DML):
1684    arg_types = {
1685        "with": False,
1686        "this": True,
1687        "expression": False,
1688        "conflict": False,
1689        "returning": False,
1690        "overwrite": False,
1691        "exists": False,
1692        "partition": False,
1693        "alternative": False,
1694        "where": False,
1695        "ignore": False,
1696        "by_name": False,
1697    }
1698
1699    def with_(
1700        self,
1701        alias: ExpOrStr,
1702        as_: ExpOrStr,
1703        recursive: t.Optional[bool] = None,
1704        append: bool = True,
1705        dialect: DialectType = None,
1706        copy: bool = True,
1707        **opts,
1708    ) -> Insert:
1709        """
1710        Append to or set the common table expressions.
1711
1712        Example:
1713            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1714            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1715
1716        Args:
1717            alias: the SQL code string to parse as the table name.
1718                If an `Expression` instance is passed, this is used as-is.
1719            as_: the SQL code string to parse as the table expression.
1720                If an `Expression` instance is passed, it will be used as-is.
1721            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1722            append: if `True`, add to any existing expressions.
1723                Otherwise, this resets the expressions.
1724            dialect: the dialect used to parse the input expression.
1725            copy: if `False`, modify this expression instance in-place.
1726            opts: other options to use to parse the input expressions.
1727
1728        Returns:
1729            The modified expression.
1730        """
1731        return _apply_cte_builder(
1732            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1733        )
1734
1735
1736class OnConflict(Expression):
1737    arg_types = {
1738        "duplicate": False,
1739        "expressions": False,
1740        "nothing": False,
1741        "key": False,
1742        "constraint": False,
1743    }
1744
1745
1746class Returning(Expression):
1747    arg_types = {"expressions": True, "into": False}
1748
1749
1750# https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
1751class Introducer(Expression):
1752    arg_types = {"this": True, "expression": True}
1753
1754
1755# national char, like n'utf8'
1756class National(Expression):
1757    pass
1758
1759
1760class LoadData(Expression):
1761    arg_types = {
1762        "this": True,
1763        "local": False,
1764        "overwrite": False,
1765        "inpath": True,
1766        "partition": False,
1767        "input_format": False,
1768        "serde": False,
1769    }
1770
1771
1772class Partition(Expression):
1773    arg_types = {"expressions": True}
1774
1775
1776class Fetch(Expression):
1777    arg_types = {
1778        "direction": False,
1779        "count": False,
1780        "percent": False,
1781        "with_ties": False,
1782    }
1783
1784
1785class Group(Expression):
1786    arg_types = {
1787        "expressions": False,
1788        "grouping_sets": False,
1789        "cube": False,
1790        "rollup": False,
1791        "totals": False,
1792        "all": False,
1793    }
1794
1795
1796class Lambda(Expression):
1797    arg_types = {"this": True, "expressions": True}
1798
1799
1800class Limit(Expression):
1801    arg_types = {"this": False, "expression": True, "offset": False}
1802
1803
1804class Literal(Condition):
1805    arg_types = {"this": True, "is_string": True}
1806
1807    @property
1808    def hashable_args(self) -> t.Any:
1809        return (self.this, self.args.get("is_string"))
1810
1811    @classmethod
1812    def number(cls, number) -> Literal:
1813        return cls(this=str(number), is_string=False)
1814
1815    @classmethod
1816    def string(cls, string) -> Literal:
1817        return cls(this=str(string), is_string=True)
1818
1819    @property
1820    def output_name(self) -> str:
1821        return self.name
1822
1823
1824class Join(Expression):
1825    arg_types = {
1826        "this": True,
1827        "on": False,
1828        "side": False,
1829        "kind": False,
1830        "using": False,
1831        "method": False,
1832        "global": False,
1833        "hint": False,
1834    }
1835
1836    @property
1837    def method(self) -> str:
1838        return self.text("method").upper()
1839
1840    @property
1841    def kind(self) -> str:
1842        return self.text("kind").upper()
1843
1844    @property
1845    def side(self) -> str:
1846        return self.text("side").upper()
1847
1848    @property
1849    def hint(self) -> str:
1850        return self.text("hint").upper()
1851
1852    @property
1853    def alias_or_name(self) -> str:
1854        return self.this.alias_or_name
1855
1856    def on(
1857        self,
1858        *expressions: t.Optional[ExpOrStr],
1859        append: bool = True,
1860        dialect: DialectType = None,
1861        copy: bool = True,
1862        **opts,
1863    ) -> Join:
1864        """
1865        Append to or set the ON expressions.
1866
1867        Example:
1868            >>> import sqlglot
1869            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1870            'JOIN x ON y = 1'
1871
1872        Args:
1873            *expressions: the SQL code strings to parse.
1874                If an `Expression` instance is passed, it will be used as-is.
1875                Multiple expressions are combined with an AND operator.
1876            append: if `True`, AND the new expressions to any existing expression.
1877                Otherwise, this resets the expression.
1878            dialect: the dialect used to parse the input expressions.
1879            copy: if `False`, modify this expression instance in-place.
1880            opts: other options to use to parse the input expressions.
1881
1882        Returns:
1883            The modified Join expression.
1884        """
1885        join = _apply_conjunction_builder(
1886            *expressions,
1887            instance=self,
1888            arg="on",
1889            append=append,
1890            dialect=dialect,
1891            copy=copy,
1892            **opts,
1893        )
1894
1895        if join.kind == "CROSS":
1896            join.set("kind", None)
1897
1898        return join
1899
1900    def using(
1901        self,
1902        *expressions: t.Optional[ExpOrStr],
1903        append: bool = True,
1904        dialect: DialectType = None,
1905        copy: bool = True,
1906        **opts,
1907    ) -> Join:
1908        """
1909        Append to or set the USING expressions.
1910
1911        Example:
1912            >>> import sqlglot
1913            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1914            'JOIN x USING (foo, bla)'
1915
1916        Args:
1917            *expressions: the SQL code strings to parse.
1918                If an `Expression` instance is passed, it will be used as-is.
1919            append: if `True`, concatenate the new expressions to the existing "using" list.
1920                Otherwise, this resets the expression.
1921            dialect: the dialect used to parse the input expressions.
1922            copy: if `False`, modify this expression instance in-place.
1923            opts: other options to use to parse the input expressions.
1924
1925        Returns:
1926            The modified Join expression.
1927        """
1928        join = _apply_list_builder(
1929            *expressions,
1930            instance=self,
1931            arg="using",
1932            append=append,
1933            dialect=dialect,
1934            copy=copy,
1935            **opts,
1936        )
1937
1938        if join.kind == "CROSS":
1939            join.set("kind", None)
1940
1941        return join
1942
1943
1944class Lateral(UDTF):
1945    arg_types = {
1946        "this": True,
1947        "view": False,
1948        "outer": False,
1949        "alias": False,
1950        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1951    }
1952
1953
1954class MatchRecognize(Expression):
1955    arg_types = {
1956        "partition_by": False,
1957        "order": False,
1958        "measures": False,
1959        "rows": False,
1960        "after": False,
1961        "pattern": False,
1962        "define": False,
1963        "alias": False,
1964    }
1965
1966
1967# Clickhouse FROM FINAL modifier
1968# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
1969class Final(Expression):
1970    pass
1971
1972
1973class Offset(Expression):
1974    arg_types = {"this": False, "expression": True}
1975
1976
1977class Order(Expression):
1978    arg_types = {
1979        "this": False,
1980        "expressions": True,
1981        "interpolate": False,
1982        "siblings": False,
1983    }
1984
1985
1986# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
1987class WithFill(Expression):
1988    arg_types = {"from": False, "to": False, "step": False}
1989
1990
1991# hive specific sorts
1992# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
1993class Cluster(Order):
1994    pass
1995
1996
1997class Distribute(Order):
1998    pass
1999
2000
2001class Sort(Order):
2002    pass
2003
2004
2005class Ordered(Expression):
2006    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2007
2008
2009class Property(Expression):
2010    arg_types = {"this": True, "value": True}
2011
2012
2013class AlgorithmProperty(Property):
2014    arg_types = {"this": True}
2015
2016
2017class AutoIncrementProperty(Property):
2018    arg_types = {"this": True}
2019
2020
2021# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2022class AutoRefreshProperty(Property):
2023    arg_types = {"this": True}
2024
2025
2026class BlockCompressionProperty(Property):
2027    arg_types = {
2028        "autotemp": False,
2029        "always": False,
2030        "default": False,
2031        "manual": False,
2032        "never": False,
2033    }
2034
2035
2036class CharacterSetProperty(Property):
2037    arg_types = {"this": True, "default": True}
2038
2039
2040class ChecksumProperty(Property):
2041    arg_types = {"on": False, "default": False}
2042
2043
2044class CollateProperty(Property):
2045    arg_types = {"this": True, "default": False}
2046
2047
2048class CopyGrantsProperty(Property):
2049    arg_types = {}
2050
2051
2052class DataBlocksizeProperty(Property):
2053    arg_types = {
2054        "size": False,
2055        "units": False,
2056        "minimum": False,
2057        "maximum": False,
2058        "default": False,
2059    }
2060
2061
2062class DefinerProperty(Property):
2063    arg_types = {"this": True}
2064
2065
2066class DistKeyProperty(Property):
2067    arg_types = {"this": True}
2068
2069
2070class DistStyleProperty(Property):
2071    arg_types = {"this": True}
2072
2073
2074class EngineProperty(Property):
2075    arg_types = {"this": True}
2076
2077
2078class HeapProperty(Property):
2079    arg_types = {}
2080
2081
2082class ToTableProperty(Property):
2083    arg_types = {"this": True}
2084
2085
2086class ExecuteAsProperty(Property):
2087    arg_types = {"this": True}
2088
2089
2090class ExternalProperty(Property):
2091    arg_types = {"this": False}
2092
2093
2094class FallbackProperty(Property):
2095    arg_types = {"no": True, "protection": False}
2096
2097
2098class FileFormatProperty(Property):
2099    arg_types = {"this": True}
2100
2101
2102class FreespaceProperty(Property):
2103    arg_types = {"this": True, "percent": False}
2104
2105
2106class InheritsProperty(Property):
2107    arg_types = {"expressions": True}
2108
2109
2110class InputModelProperty(Property):
2111    arg_types = {"this": True}
2112
2113
2114class OutputModelProperty(Property):
2115    arg_types = {"this": True}
2116
2117
2118class IsolatedLoadingProperty(Property):
2119    arg_types = {
2120        "no": False,
2121        "concurrent": False,
2122        "for_all": False,
2123        "for_insert": False,
2124        "for_none": False,
2125    }
2126
2127
2128class JournalProperty(Property):
2129    arg_types = {
2130        "no": False,
2131        "dual": False,
2132        "before": False,
2133        "local": False,
2134        "after": False,
2135    }
2136
2137
2138class LanguageProperty(Property):
2139    arg_types = {"this": True}
2140
2141
2142# spark ddl
2143class ClusteredByProperty(Property):
2144    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2145
2146
2147class DictProperty(Property):
2148    arg_types = {"this": True, "kind": True, "settings": False}
2149
2150
2151class DictSubProperty(Property):
2152    pass
2153
2154
2155class DictRange(Property):
2156    arg_types = {"this": True, "min": True, "max": True}
2157
2158
2159# Clickhouse CREATE ... ON CLUSTER modifier
2160# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2161class OnCluster(Property):
2162    arg_types = {"this": True}
2163
2164
2165class LikeProperty(Property):
2166    arg_types = {"this": True, "expressions": False}
2167
2168
2169class LocationProperty(Property):
2170    arg_types = {"this": True}
2171
2172
2173class LockingProperty(Property):
2174    arg_types = {
2175        "this": False,
2176        "kind": True,
2177        "for_or_in": False,
2178        "lock_type": True,
2179        "override": False,
2180    }
2181
2182
2183class LogProperty(Property):
2184    arg_types = {"no": True}
2185
2186
2187class MaterializedProperty(Property):
2188    arg_types = {"this": False}
2189
2190
2191class MergeBlockRatioProperty(Property):
2192    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2193
2194
2195class NoPrimaryIndexProperty(Property):
2196    arg_types = {}
2197
2198
2199class OnProperty(Property):
2200    arg_types = {"this": True}
2201
2202
2203class OnCommitProperty(Property):
2204    arg_types = {"delete": False}
2205
2206
2207class PartitionedByProperty(Property):
2208    arg_types = {"this": True}
2209
2210
2211# https://www.postgresql.org/docs/current/sql-createtable.html
2212class PartitionBoundSpec(Expression):
2213    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2214    arg_types = {
2215        "this": False,
2216        "expression": False,
2217        "from_expressions": False,
2218        "to_expressions": False,
2219    }
2220
2221
2222class PartitionedOfProperty(Property):
2223    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2224    arg_types = {"this": True, "expression": True}
2225
2226
2227class RemoteWithConnectionModelProperty(Property):
2228    arg_types = {"this": True}
2229
2230
2231class ReturnsProperty(Property):
2232    arg_types = {"this": True, "is_table": False, "table": False}
2233
2234
2235class RowFormatProperty(Property):
2236    arg_types = {"this": True}
2237
2238
2239class RowFormatDelimitedProperty(Property):
2240    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2241    arg_types = {
2242        "fields": False,
2243        "escaped": False,
2244        "collection_items": False,
2245        "map_keys": False,
2246        "lines": False,
2247        "null": False,
2248        "serde": False,
2249    }
2250
2251
2252class RowFormatSerdeProperty(Property):
2253    arg_types = {"this": True, "serde_properties": False}
2254
2255
2256# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
2257class QueryTransform(Expression):
2258    arg_types = {
2259        "expressions": True,
2260        "command_script": True,
2261        "schema": False,
2262        "row_format_before": False,
2263        "record_writer": False,
2264        "row_format_after": False,
2265        "record_reader": False,
2266    }
2267
2268
2269class SampleProperty(Property):
2270    arg_types = {"this": True}
2271
2272
2273class SchemaCommentProperty(Property):
2274    arg_types = {"this": True}
2275
2276
2277class SerdeProperties(Property):
2278    arg_types = {"expressions": True}
2279
2280
2281class SetProperty(Property):
2282    arg_types = {"multi": True}
2283
2284
2285class SetConfigProperty(Property):
2286    arg_types = {"this": True}
2287
2288
2289class SettingsProperty(Property):
2290    arg_types = {"expressions": True}
2291
2292
2293class SortKeyProperty(Property):
2294    arg_types = {"this": True, "compound": False}
2295
2296
2297class SqlReadWriteProperty(Property):
2298    arg_types = {"this": True}
2299
2300
2301class SqlSecurityProperty(Property):
2302    arg_types = {"definer": True}
2303
2304
2305class StabilityProperty(Property):
2306    arg_types = {"this": True}
2307
2308
2309class TemporaryProperty(Property):
2310    arg_types = {}
2311
2312
2313class TransformModelProperty(Property):
2314    arg_types = {"expressions": True}
2315
2316
2317class TransientProperty(Property):
2318    arg_types = {"this": False}
2319
2320
2321class VolatileProperty(Property):
2322    arg_types = {"this": False}
2323
2324
2325class WithDataProperty(Property):
2326    arg_types = {"no": True, "statistics": False}
2327
2328
2329class WithJournalTableProperty(Property):
2330    arg_types = {"this": True}
2331
2332
2333class WithSystemVersioningProperty(Property):
2334    # this -> history table name, expression -> data consistency check
2335    arg_types = {"this": False, "expression": False}
2336
2337
2338class Properties(Expression):
2339    arg_types = {"expressions": True}
2340
2341    NAME_TO_PROPERTY = {
2342        "ALGORITHM": AlgorithmProperty,
2343        "AUTO_INCREMENT": AutoIncrementProperty,
2344        "CHARACTER SET": CharacterSetProperty,
2345        "CLUSTERED_BY": ClusteredByProperty,
2346        "COLLATE": CollateProperty,
2347        "COMMENT": SchemaCommentProperty,
2348        "DEFINER": DefinerProperty,
2349        "DISTKEY": DistKeyProperty,
2350        "DISTSTYLE": DistStyleProperty,
2351        "ENGINE": EngineProperty,
2352        "EXECUTE AS": ExecuteAsProperty,
2353        "FORMAT": FileFormatProperty,
2354        "LANGUAGE": LanguageProperty,
2355        "LOCATION": LocationProperty,
2356        "PARTITIONED_BY": PartitionedByProperty,
2357        "RETURNS": ReturnsProperty,
2358        "ROW_FORMAT": RowFormatProperty,
2359        "SORTKEY": SortKeyProperty,
2360    }
2361
2362    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2363
2364    # CREATE property locations
2365    # Form: schema specified
2366    #   create [POST_CREATE]
2367    #     table a [POST_NAME]
2368    #     (b int) [POST_SCHEMA]
2369    #     with ([POST_WITH])
2370    #     index (b) [POST_INDEX]
2371    #
2372    # Form: alias selection
2373    #   create [POST_CREATE]
2374    #     table a [POST_NAME]
2375    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2376    #     index (c) [POST_INDEX]
2377    class Location(AutoName):
2378        POST_CREATE = auto()
2379        POST_NAME = auto()
2380        POST_SCHEMA = auto()
2381        POST_WITH = auto()
2382        POST_ALIAS = auto()
2383        POST_EXPRESSION = auto()
2384        POST_INDEX = auto()
2385        UNSUPPORTED = auto()
2386
2387    @classmethod
2388    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2389        expressions = []
2390        for key, value in properties_dict.items():
2391            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2392            if property_cls:
2393                expressions.append(property_cls(this=convert(value)))
2394            else:
2395                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2396
2397        return cls(expressions=expressions)
2398
2399
2400class Qualify(Expression):
2401    pass
2402
2403
2404class InputOutputFormat(Expression):
2405    arg_types = {"input_format": False, "output_format": False}
2406
2407
2408# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
2409class Return(Expression):
2410    pass
2411
2412
2413class Reference(Expression):
2414    arg_types = {"this": True, "expressions": False, "options": False}
2415
2416
2417class Tuple(Expression):
2418    arg_types = {"expressions": False}
2419
2420    def isin(
2421        self,
2422        *expressions: t.Any,
2423        query: t.Optional[ExpOrStr] = None,
2424        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2425        copy: bool = True,
2426        **opts,
2427    ) -> In:
2428        return In(
2429            this=maybe_copy(self, copy),
2430            expressions=[convert(e, copy=copy) for e in expressions],
2431            query=maybe_parse(query, copy=copy, **opts) if query else None,
2432            unnest=(
2433                Unnest(
2434                    expressions=[
2435                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2436                        for e in ensure_list(unnest)
2437                    ]
2438                )
2439                if unnest
2440                else None
2441            ),
2442        )
2443
2444
2445class Subqueryable(Unionable):
2446    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2447        """
2448        Convert this expression to an aliased expression that can be used as a Subquery.
2449
2450        Example:
2451            >>> subquery = Select().select("x").from_("tbl").subquery()
2452            >>> Select().select("x").from_(subquery).sql()
2453            'SELECT x FROM (SELECT x FROM tbl)'
2454
2455        Args:
2456            alias (str | Identifier): an optional alias for the subquery
2457            copy (bool): if `False`, modify this expression instance in-place.
2458
2459        Returns:
2460            Alias: the subquery
2461        """
2462        instance = maybe_copy(self, copy)
2463        if not isinstance(alias, Expression):
2464            alias = TableAlias(this=to_identifier(alias)) if alias else None
2465
2466        return Subquery(this=instance, alias=alias)
2467
2468    def limit(
2469        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2470    ) -> Select:
2471        raise NotImplementedError
2472
2473    @property
2474    def ctes(self):
2475        with_ = self.args.get("with")
2476        if not with_:
2477            return []
2478        return with_.expressions
2479
2480    @property
2481    def selects(self) -> t.List[Expression]:
2482        raise NotImplementedError("Subqueryable objects must implement `selects`")
2483
2484    @property
2485    def named_selects(self) -> t.List[str]:
2486        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2487
2488    def select(
2489        self,
2490        *expressions: t.Optional[ExpOrStr],
2491        append: bool = True,
2492        dialect: DialectType = None,
2493        copy: bool = True,
2494        **opts,
2495    ) -> Subqueryable:
2496        raise NotImplementedError("Subqueryable objects must implement `select`")
2497
2498    def with_(
2499        self,
2500        alias: ExpOrStr,
2501        as_: ExpOrStr,
2502        recursive: t.Optional[bool] = None,
2503        append: bool = True,
2504        dialect: DialectType = None,
2505        copy: bool = True,
2506        **opts,
2507    ) -> Subqueryable:
2508        """
2509        Append to or set the common table expressions.
2510
2511        Example:
2512            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2513            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2514
2515        Args:
2516            alias: the SQL code string to parse as the table name.
2517                If an `Expression` instance is passed, this is used as-is.
2518            as_: the SQL code string to parse as the table expression.
2519                If an `Expression` instance is passed, it will be used as-is.
2520            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2521            append: if `True`, add to any existing expressions.
2522                Otherwise, this resets the expressions.
2523            dialect: the dialect used to parse the input expression.
2524            copy: if `False`, modify this expression instance in-place.
2525            opts: other options to use to parse the input expressions.
2526
2527        Returns:
2528            The modified expression.
2529        """
2530        return _apply_cte_builder(
2531            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2532        )
2533
2534
2535QUERY_MODIFIERS = {
2536    "match": False,
2537    "laterals": False,
2538    "joins": False,
2539    "connect": False,
2540    "pivots": False,
2541    "where": False,
2542    "group": False,
2543    "having": False,
2544    "qualify": False,
2545    "windows": False,
2546    "distribute": False,
2547    "sort": False,
2548    "cluster": False,
2549    "order": False,
2550    "limit": False,
2551    "offset": False,
2552    "locks": False,
2553    "sample": False,
2554    "settings": False,
2555    "format": False,
2556}
2557
2558
2559# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
2560class WithTableHint(Expression):
2561    arg_types = {"expressions": True}
2562
2563
2564# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
2565class IndexTableHint(Expression):
2566    arg_types = {"this": True, "expressions": False, "target": False}
2567
2568
2569# https://docs.snowflake.com/en/sql-reference/constructs/at-before
2570class HistoricalData(Expression):
2571    arg_types = {"this": True, "kind": True, "expression": True}
2572
2573
2574class Table(Expression):
2575    arg_types = {
2576        "this": True,
2577        "alias": False,
2578        "db": False,
2579        "catalog": False,
2580        "laterals": False,
2581        "joins": False,
2582        "pivots": False,
2583        "hints": False,
2584        "system_time": False,
2585        "version": False,
2586        "format": False,
2587        "pattern": False,
2588        "ordinality": False,
2589        "when": False,
2590    }
2591
2592    @property
2593    def name(self) -> str:
2594        if isinstance(self.this, Func):
2595            return ""
2596        return self.this.name
2597
2598    @property
2599    def db(self) -> str:
2600        return self.text("db")
2601
2602    @property
2603    def catalog(self) -> str:
2604        return self.text("catalog")
2605
2606    @property
2607    def selects(self) -> t.List[Expression]:
2608        return []
2609
2610    @property
2611    def named_selects(self) -> t.List[str]:
2612        return []
2613
2614    @property
2615    def parts(self) -> t.List[Expression]:
2616        """Return the parts of a table in order catalog, db, table."""
2617        parts: t.List[Expression] = []
2618
2619        for arg in ("catalog", "db", "this"):
2620            part = self.args.get(arg)
2621
2622            if isinstance(part, Dot):
2623                parts.extend(part.flatten())
2624            elif isinstance(part, Expression):
2625                parts.append(part)
2626
2627        return parts
2628
2629    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2630        parts = self.parts
2631        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2632        alias = self.args.get("alias")
2633        if alias:
2634            col = alias_(col, alias.this, copy=copy)
2635        return col
2636
2637
2638class Union(Subqueryable):
2639    arg_types = {
2640        "with": False,
2641        "this": True,
2642        "expression": True,
2643        "distinct": False,
2644        "by_name": False,
2645        **QUERY_MODIFIERS,
2646    }
2647
2648    def limit(
2649        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2650    ) -> Select:
2651        """
2652        Set the LIMIT expression.
2653
2654        Example:
2655            >>> select("1").union(select("1")).limit(1).sql()
2656            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2657
2658        Args:
2659            expression: the SQL code string to parse.
2660                This can also be an integer.
2661                If a `Limit` instance is passed, this is used as-is.
2662                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2663            dialect: the dialect used to parse the input expression.
2664            copy: if `False`, modify this expression instance in-place.
2665            opts: other options to use to parse the input expressions.
2666
2667        Returns:
2668            The limited subqueryable.
2669        """
2670        return (
2671            select("*")
2672            .from_(self.subquery(alias="_l_0", copy=copy))
2673            .limit(expression, dialect=dialect, copy=False, **opts)
2674        )
2675
2676    def select(
2677        self,
2678        *expressions: t.Optional[ExpOrStr],
2679        append: bool = True,
2680        dialect: DialectType = None,
2681        copy: bool = True,
2682        **opts,
2683    ) -> Union:
2684        """Append to or set the SELECT of the union recursively.
2685
2686        Example:
2687            >>> from sqlglot import parse_one
2688            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2689            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2690
2691        Args:
2692            *expressions: the SQL code strings to parse.
2693                If an `Expression` instance is passed, it will be used as-is.
2694            append: if `True`, add to any existing expressions.
2695                Otherwise, this resets the expressions.
2696            dialect: the dialect used to parse the input expressions.
2697            copy: if `False`, modify this expression instance in-place.
2698            opts: other options to use to parse the input expressions.
2699
2700        Returns:
2701            Union: the modified expression.
2702        """
2703        this = self.copy() if copy else self
2704        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2705        this.expression.unnest().select(
2706            *expressions, append=append, dialect=dialect, copy=False, **opts
2707        )
2708        return this
2709
2710    @property
2711    def named_selects(self) -> t.List[str]:
2712        return self.this.unnest().named_selects
2713
2714    @property
2715    def is_star(self) -> bool:
2716        return self.this.is_star or self.expression.is_star
2717
2718    @property
2719    def selects(self) -> t.List[Expression]:
2720        return self.this.unnest().selects
2721
2722    @property
2723    def left(self) -> Expression:
2724        return self.this
2725
2726    @property
2727    def right(self) -> Expression:
2728        return self.expression
2729
2730
2731class Except(Union):
2732    pass
2733
2734
2735class Intersect(Union):
2736    pass
2737
2738
2739class Unnest(UDTF):
2740    arg_types = {
2741        "expressions": True,
2742        "alias": False,
2743        "offset": False,
2744    }
2745
2746    @property
2747    def selects(self) -> t.List[Expression]:
2748        columns = super().selects
2749        offset = self.args.get("offset")
2750        if offset:
2751            columns = columns + [to_identifier("offset") if offset is True else offset]
2752        return columns
2753
2754
2755class Update(Expression):
2756    arg_types = {
2757        "with": False,
2758        "this": False,
2759        "expressions": True,
2760        "from": False,
2761        "where": False,
2762        "returning": False,
2763        "order": False,
2764        "limit": False,
2765    }
2766
2767
2768class Values(UDTF):
2769    arg_types = {"expressions": True, "alias": False}
2770
2771
2772class Var(Expression):
2773    pass
2774
2775
2776class Version(Expression):
2777    """
2778    Time travel, iceberg, bigquery etc
2779    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2780    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2781    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2782    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2783    this is either TIMESTAMP or VERSION
2784    kind is ("AS OF", "BETWEEN")
2785    """
2786
2787    arg_types = {"this": True, "kind": True, "expression": False}
2788
2789
2790class Schema(Expression):
2791    arg_types = {"this": False, "expressions": False}
2792
2793
2794# https://dev.mysql.com/doc/refman/8.0/en/select.html
2795# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
2796class Lock(Expression):
2797    arg_types = {"update": True, "expressions": False, "wait": False}
2798
2799
2800class Select(Subqueryable):
2801    arg_types = {
2802        "with": False,
2803        "kind": False,
2804        "expressions": False,
2805        "hint": False,
2806        "distinct": False,
2807        "into": False,
2808        "from": False,
2809        **QUERY_MODIFIERS,
2810    }
2811
2812    def from_(
2813        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2814    ) -> Select:
2815        """
2816        Set the FROM expression.
2817
2818        Example:
2819            >>> Select().from_("tbl").select("x").sql()
2820            'SELECT x FROM tbl'
2821
2822        Args:
2823            expression : the SQL code strings to parse.
2824                If a `From` instance is passed, this is used as-is.
2825                If another `Expression` instance is passed, it will be wrapped in a `From`.
2826            dialect: the dialect used to parse the input expression.
2827            copy: if `False`, modify this expression instance in-place.
2828            opts: other options to use to parse the input expressions.
2829
2830        Returns:
2831            The modified Select expression.
2832        """
2833        return _apply_builder(
2834            expression=expression,
2835            instance=self,
2836            arg="from",
2837            into=From,
2838            prefix="FROM",
2839            dialect=dialect,
2840            copy=copy,
2841            **opts,
2842        )
2843
2844    def group_by(
2845        self,
2846        *expressions: t.Optional[ExpOrStr],
2847        append: bool = True,
2848        dialect: DialectType = None,
2849        copy: bool = True,
2850        **opts,
2851    ) -> Select:
2852        """
2853        Set the GROUP BY expression.
2854
2855        Example:
2856            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2857            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2858
2859        Args:
2860            *expressions: the SQL code strings to parse.
2861                If a `Group` instance is passed, this is used as-is.
2862                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2863                If nothing is passed in then a group by is not applied to the expression
2864            append: if `True`, add to any existing expressions.
2865                Otherwise, this flattens all the `Group` expression into a single expression.
2866            dialect: the dialect used to parse the input expression.
2867            copy: if `False`, modify this expression instance in-place.
2868            opts: other options to use to parse the input expressions.
2869
2870        Returns:
2871            The modified Select expression.
2872        """
2873        if not expressions:
2874            return self if not copy else self.copy()
2875
2876        return _apply_child_list_builder(
2877            *expressions,
2878            instance=self,
2879            arg="group",
2880            append=append,
2881            copy=copy,
2882            prefix="GROUP BY",
2883            into=Group,
2884            dialect=dialect,
2885            **opts,
2886        )
2887
2888    def order_by(
2889        self,
2890        *expressions: t.Optional[ExpOrStr],
2891        append: bool = True,
2892        dialect: DialectType = None,
2893        copy: bool = True,
2894        **opts,
2895    ) -> Select:
2896        """
2897        Set the ORDER BY expression.
2898
2899        Example:
2900            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2901            'SELECT x FROM tbl ORDER BY x DESC'
2902
2903        Args:
2904            *expressions: the SQL code strings to parse.
2905                If a `Group` instance is passed, this is used as-is.
2906                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2907            append: if `True`, add to any existing expressions.
2908                Otherwise, this flattens all the `Order` expression into a single expression.
2909            dialect: the dialect used to parse the input expression.
2910            copy: if `False`, modify this expression instance in-place.
2911            opts: other options to use to parse the input expressions.
2912
2913        Returns:
2914            The modified Select expression.
2915        """
2916        return _apply_child_list_builder(
2917            *expressions,
2918            instance=self,
2919            arg="order",
2920            append=append,
2921            copy=copy,
2922            prefix="ORDER BY",
2923            into=Order,
2924            dialect=dialect,
2925            **opts,
2926        )
2927
2928    def sort_by(
2929        self,
2930        *expressions: t.Optional[ExpOrStr],
2931        append: bool = True,
2932        dialect: DialectType = None,
2933        copy: bool = True,
2934        **opts,
2935    ) -> Select:
2936        """
2937        Set the SORT BY expression.
2938
2939        Example:
2940            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2941            'SELECT x FROM tbl SORT BY x DESC'
2942
2943        Args:
2944            *expressions: the SQL code strings to parse.
2945                If a `Group` instance is passed, this is used as-is.
2946                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2947            append: if `True`, add to any existing expressions.
2948                Otherwise, this flattens all the `Order` expression into a single expression.
2949            dialect: the dialect used to parse the input expression.
2950            copy: if `False`, modify this expression instance in-place.
2951            opts: other options to use to parse the input expressions.
2952
2953        Returns:
2954            The modified Select expression.
2955        """
2956        return _apply_child_list_builder(
2957            *expressions,
2958            instance=self,
2959            arg="sort",
2960            append=append,
2961            copy=copy,
2962            prefix="SORT BY",
2963            into=Sort,
2964            dialect=dialect,
2965            **opts,
2966        )
2967
2968    def cluster_by(
2969        self,
2970        *expressions: t.Optional[ExpOrStr],
2971        append: bool = True,
2972        dialect: DialectType = None,
2973        copy: bool = True,
2974        **opts,
2975    ) -> Select:
2976        """
2977        Set the CLUSTER BY expression.
2978
2979        Example:
2980            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2981            'SELECT x FROM tbl CLUSTER BY x DESC'
2982
2983        Args:
2984            *expressions: the SQL code strings to parse.
2985                If a `Group` instance is passed, this is used as-is.
2986                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2987            append: if `True`, add to any existing expressions.
2988                Otherwise, this flattens all the `Order` expression into a single expression.
2989            dialect: the dialect used to parse the input expression.
2990            copy: if `False`, modify this expression instance in-place.
2991            opts: other options to use to parse the input expressions.
2992
2993        Returns:
2994            The modified Select expression.
2995        """
2996        return _apply_child_list_builder(
2997            *expressions,
2998            instance=self,
2999            arg="cluster",
3000            append=append,
3001            copy=copy,
3002            prefix="CLUSTER BY",
3003            into=Cluster,
3004            dialect=dialect,
3005            **opts,
3006        )
3007
3008    def limit(
3009        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3010    ) -> Select:
3011        """
3012        Set the LIMIT expression.
3013
3014        Example:
3015            >>> Select().from_("tbl").select("x").limit(10).sql()
3016            'SELECT x FROM tbl LIMIT 10'
3017
3018        Args:
3019            expression: the SQL code string to parse.
3020                This can also be an integer.
3021                If a `Limit` instance is passed, this is used as-is.
3022                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
3023            dialect: the dialect used to parse the input expression.
3024            copy: if `False`, modify this expression instance in-place.
3025            opts: other options to use to parse the input expressions.
3026
3027        Returns:
3028            Select: the modified expression.
3029        """
3030        return _apply_builder(
3031            expression=expression,
3032            instance=self,
3033            arg="limit",
3034            into=Limit,
3035            prefix="LIMIT",
3036            dialect=dialect,
3037            copy=copy,
3038            into_arg="expression",
3039            **opts,
3040        )
3041
3042    def offset(
3043        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3044    ) -> Select:
3045        """
3046        Set the OFFSET expression.
3047
3048        Example:
3049            >>> Select().from_("tbl").select("x").offset(10).sql()
3050            'SELECT x FROM tbl OFFSET 10'
3051
3052        Args:
3053            expression: the SQL code string to parse.
3054                This can also be an integer.
3055                If a `Offset` instance is passed, this is used as-is.
3056                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3057            dialect: the dialect used to parse the input expression.
3058            copy: if `False`, modify this expression instance in-place.
3059            opts: other options to use to parse the input expressions.
3060
3061        Returns:
3062            The modified Select expression.
3063        """
3064        return _apply_builder(
3065            expression=expression,
3066            instance=self,
3067            arg="offset",
3068            into=Offset,
3069            prefix="OFFSET",
3070            dialect=dialect,
3071            copy=copy,
3072            into_arg="expression",
3073            **opts,
3074        )
3075
3076    def select(
3077        self,
3078        *expressions: t.Optional[ExpOrStr],
3079        append: bool = True,
3080        dialect: DialectType = None,
3081        copy: bool = True,
3082        **opts,
3083    ) -> Select:
3084        """
3085        Append to or set the SELECT expressions.
3086
3087        Example:
3088            >>> Select().select("x", "y").sql()
3089            'SELECT x, y'
3090
3091        Args:
3092            *expressions: the SQL code strings to parse.
3093                If an `Expression` instance is passed, it will be used as-is.
3094            append: if `True`, add to any existing expressions.
3095                Otherwise, this resets the expressions.
3096            dialect: the dialect used to parse the input expressions.
3097            copy: if `False`, modify this expression instance in-place.
3098            opts: other options to use to parse the input expressions.
3099
3100        Returns:
3101            The modified Select expression.
3102        """
3103        return _apply_list_builder(
3104            *expressions,
3105            instance=self,
3106            arg="expressions",
3107            append=append,
3108            dialect=dialect,
3109            copy=copy,
3110            **opts,
3111        )
3112
3113    def lateral(
3114        self,
3115        *expressions: t.Optional[ExpOrStr],
3116        append: bool = True,
3117        dialect: DialectType = None,
3118        copy: bool = True,
3119        **opts,
3120    ) -> Select:
3121        """
3122        Append to or set the LATERAL expressions.
3123
3124        Example:
3125            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3126            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3127
3128        Args:
3129            *expressions: the SQL code strings to parse.
3130                If an `Expression` instance is passed, it will be used as-is.
3131            append: if `True`, add to any existing expressions.
3132                Otherwise, this resets the expressions.
3133            dialect: the dialect used to parse the input expressions.
3134            copy: if `False`, modify this expression instance in-place.
3135            opts: other options to use to parse the input expressions.
3136
3137        Returns:
3138            The modified Select expression.
3139        """
3140        return _apply_list_builder(
3141            *expressions,
3142            instance=self,
3143            arg="laterals",
3144            append=append,
3145            into=Lateral,
3146            prefix="LATERAL VIEW",
3147            dialect=dialect,
3148            copy=copy,
3149            **opts,
3150        )
3151
3152    def join(
3153        self,
3154        expression: ExpOrStr,
3155        on: t.Optional[ExpOrStr] = None,
3156        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3157        append: bool = True,
3158        join_type: t.Optional[str] = None,
3159        join_alias: t.Optional[Identifier | str] = None,
3160        dialect: DialectType = None,
3161        copy: bool = True,
3162        **opts,
3163    ) -> Select:
3164        """
3165        Append to or set the JOIN expressions.
3166
3167        Example:
3168            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3169            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3170
3171            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3172            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3173
3174            Use `join_type` to change the type of join:
3175
3176            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3177            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3178
3179        Args:
3180            expression: the SQL code string to parse.
3181                If an `Expression` instance is passed, it will be used as-is.
3182            on: optionally specify the join "on" criteria as a SQL string.
3183                If an `Expression` instance is passed, it will be used as-is.
3184            using: optionally specify the join "using" criteria as a SQL string.
3185                If an `Expression` instance is passed, it will be used as-is.
3186            append: if `True`, add to any existing expressions.
3187                Otherwise, this resets the expressions.
3188            join_type: if set, alter the parsed join type.
3189            join_alias: an optional alias for the joined source.
3190            dialect: the dialect used to parse the input expressions.
3191            copy: if `False`, modify this expression instance in-place.
3192            opts: other options to use to parse the input expressions.
3193
3194        Returns:
3195            Select: the modified expression.
3196        """
3197        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3198
3199        try:
3200            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3201        except ParseError:
3202            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3203
3204        join = expression if isinstance(expression, Join) else Join(this=expression)
3205
3206        if isinstance(join.this, Select):
3207            join.this.replace(join.this.subquery())
3208
3209        if join_type:
3210            method: t.Optional[Token]
3211            side: t.Optional[Token]
3212            kind: t.Optional[Token]
3213
3214            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3215
3216            if method:
3217                join.set("method", method.text)
3218            if side:
3219                join.set("side", side.text)
3220            if kind:
3221                join.set("kind", kind.text)
3222
3223        if on:
3224            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3225            join.set("on", on)
3226
3227        if using:
3228            join = _apply_list_builder(
3229                *ensure_list(using),
3230                instance=join,
3231                arg="using",
3232                append=append,
3233                copy=copy,
3234                into=Identifier,
3235                **opts,
3236            )
3237
3238        if join_alias:
3239            join.set("this", alias_(join.this, join_alias, table=True))
3240
3241        return _apply_list_builder(
3242            join,
3243            instance=self,
3244            arg="joins",
3245            append=append,
3246            copy=copy,
3247            **opts,
3248        )
3249
3250    def where(
3251        self,
3252        *expressions: t.Optional[ExpOrStr],
3253        append: bool = True,
3254        dialect: DialectType = None,
3255        copy: bool = True,
3256        **opts,
3257    ) -> Select:
3258        """
3259        Append to or set the WHERE expressions.
3260
3261        Example:
3262            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3263            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3264
3265        Args:
3266            *expressions: the SQL code strings to parse.
3267                If an `Expression` instance is passed, it will be used as-is.
3268                Multiple expressions are combined with an AND operator.
3269            append: if `True`, AND the new expressions to any existing expression.
3270                Otherwise, this resets the expression.
3271            dialect: the dialect used to parse the input expressions.
3272            copy: if `False`, modify this expression instance in-place.
3273            opts: other options to use to parse the input expressions.
3274
3275        Returns:
3276            Select: the modified expression.
3277        """
3278        return _apply_conjunction_builder(
3279            *expressions,
3280            instance=self,
3281            arg="where",
3282            append=append,
3283            into=Where,
3284            dialect=dialect,
3285            copy=copy,
3286            **opts,
3287        )
3288
3289    def having(
3290        self,
3291        *expressions: t.Optional[ExpOrStr],
3292        append: bool = True,
3293        dialect: DialectType = None,
3294        copy: bool = True,
3295        **opts,
3296    ) -> Select:
3297        """
3298        Append to or set the HAVING expressions.
3299
3300        Example:
3301            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3302            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3303
3304        Args:
3305            *expressions: the SQL code strings to parse.
3306                If an `Expression` instance is passed, it will be used as-is.
3307                Multiple expressions are combined with an AND operator.
3308            append: if `True`, AND the new expressions to any existing expression.
3309                Otherwise, this resets the expression.
3310            dialect: the dialect used to parse the input expressions.
3311            copy: if `False`, modify this expression instance in-place.
3312            opts: other options to use to parse the input expressions.
3313
3314        Returns:
3315            The modified Select expression.
3316        """
3317        return _apply_conjunction_builder(
3318            *expressions,
3319            instance=self,
3320            arg="having",
3321            append=append,
3322            into=Having,
3323            dialect=dialect,
3324            copy=copy,
3325            **opts,
3326        )
3327
3328    def window(
3329        self,
3330        *expressions: t.Optional[ExpOrStr],
3331        append: bool = True,
3332        dialect: DialectType = None,
3333        copy: bool = True,
3334        **opts,
3335    ) -> Select:
3336        return _apply_list_builder(
3337            *expressions,
3338            instance=self,
3339            arg="windows",
3340            append=append,
3341            into=Window,
3342            dialect=dialect,
3343            copy=copy,
3344            **opts,
3345        )
3346
3347    def qualify(
3348        self,
3349        *expressions: t.Optional[ExpOrStr],
3350        append: bool = True,
3351        dialect: DialectType = None,
3352        copy: bool = True,
3353        **opts,
3354    ) -> Select:
3355        return _apply_conjunction_builder(
3356            *expressions,
3357            instance=self,
3358            arg="qualify",
3359            append=append,
3360            into=Qualify,
3361            dialect=dialect,
3362            copy=copy,
3363            **opts,
3364        )
3365
3366    def distinct(
3367        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3368    ) -> Select:
3369        """
3370        Set the OFFSET expression.
3371
3372        Example:
3373            >>> Select().from_("tbl").select("x").distinct().sql()
3374            'SELECT DISTINCT x FROM tbl'
3375
3376        Args:
3377            ons: the expressions to distinct on
3378            distinct: whether the Select should be distinct
3379            copy: if `False`, modify this expression instance in-place.
3380
3381        Returns:
3382            Select: the modified expression.
3383        """
3384        instance = maybe_copy(self, copy)
3385        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3386        instance.set("distinct", Distinct(on=on) if distinct else None)
3387        return instance
3388
3389    def ctas(
3390        self,
3391        table: ExpOrStr,
3392        properties: t.Optional[t.Dict] = None,
3393        dialect: DialectType = None,
3394        copy: bool = True,
3395        **opts,
3396    ) -> Create:
3397        """
3398        Convert this expression to a CREATE TABLE AS statement.
3399
3400        Example:
3401            >>> Select().select("*").from_("tbl").ctas("x").sql()
3402            'CREATE TABLE x AS SELECT * FROM tbl'
3403
3404        Args:
3405            table: the SQL code string to parse as the table name.
3406                If another `Expression` instance is passed, it will be used as-is.
3407            properties: an optional mapping of table properties
3408            dialect: the dialect used to parse the input table.
3409            copy: if `False`, modify this expression instance in-place.
3410            opts: other options to use to parse the input table.
3411
3412        Returns:
3413            The new Create expression.
3414        """
3415        instance = maybe_copy(self, copy)
3416        table_expression = maybe_parse(
3417            table,
3418            into=Table,
3419            dialect=dialect,
3420            **opts,
3421        )
3422        properties_expression = None
3423        if properties:
3424            properties_expression = Properties.from_dict(properties)
3425
3426        return Create(
3427            this=table_expression,
3428            kind="TABLE",
3429            expression=instance,
3430            properties=properties_expression,
3431        )
3432
3433    def lock(self, update: bool = True, copy: bool = True) -> Select:
3434        """
3435        Set the locking read mode for this expression.
3436
3437        Examples:
3438            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3439            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3440
3441            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3442            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3443
3444        Args:
3445            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3446            copy: if `False`, modify this expression instance in-place.
3447
3448        Returns:
3449            The modified expression.
3450        """
3451        inst = maybe_copy(self, copy)
3452        inst.set("locks", [Lock(update=update)])
3453
3454        return inst
3455
3456    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3457        """
3458        Set hints for this expression.
3459
3460        Examples:
3461            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3462            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3463
3464        Args:
3465            hints: The SQL code strings to parse as the hints.
3466                If an `Expression` instance is passed, it will be used as-is.
3467            dialect: The dialect used to parse the hints.
3468            copy: If `False`, modify this expression instance in-place.
3469
3470        Returns:
3471            The modified expression.
3472        """
3473        inst = maybe_copy(self, copy)
3474        inst.set(
3475            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3476        )
3477
3478        return inst
3479
3480    @property
3481    def named_selects(self) -> t.List[str]:
3482        return [e.output_name for e in self.expressions if e.alias_or_name]
3483
3484    @property
3485    def is_star(self) -> bool:
3486        return any(expression.is_star for expression in self.expressions)
3487
3488    @property
3489    def selects(self) -> t.List[Expression]:
3490        return self.expressions
3491
3492
3493class Subquery(DerivedTable, Unionable):
3494    arg_types = {
3495        "this": True,
3496        "alias": False,
3497        "with": False,
3498        **QUERY_MODIFIERS,
3499    }
3500
3501    def unnest(self):
3502        """
3503        Returns the first non subquery.
3504        """
3505        expression = self
3506        while isinstance(expression, Subquery):
3507            expression = expression.this
3508        return expression
3509
3510    def unwrap(self) -> Subquery:
3511        expression = self
3512        while expression.same_parent and expression.is_wrapper:
3513            expression = t.cast(Subquery, expression.parent)
3514        return expression
3515
3516    @property
3517    def is_wrapper(self) -> bool:
3518        """
3519        Whether this Subquery acts as a simple wrapper around another expression.
3520
3521        SELECT * FROM (((SELECT * FROM t)))
3522                      ^
3523                      This corresponds to a "wrapper" Subquery node
3524        """
3525        return all(v is None for k, v in self.args.items() if k != "this")
3526
3527    @property
3528    def is_star(self) -> bool:
3529        return self.this.is_star
3530
3531    @property
3532    def output_name(self) -> str:
3533        return self.alias
3534
3535
3536class TableSample(Expression):
3537    arg_types = {
3538        "this": False,
3539        "expressions": False,
3540        "method": False,
3541        "bucket_numerator": False,
3542        "bucket_denominator": False,
3543        "bucket_field": False,
3544        "percent": False,
3545        "rows": False,
3546        "size": False,
3547        "seed": False,
3548    }
3549
3550
3551class Tag(Expression):
3552    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3553
3554    arg_types = {
3555        "this": False,
3556        "prefix": False,
3557        "postfix": False,
3558    }
3559
3560
3561# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
3562# https://duckdb.org/docs/sql/statements/pivot
3563class Pivot(Expression):
3564    arg_types = {
3565        "this": False,
3566        "alias": False,
3567        "expressions": False,
3568        "field": False,
3569        "unpivot": False,
3570        "using": False,
3571        "group": False,
3572        "columns": False,
3573        "include_nulls": False,
3574    }
3575
3576    @property
3577    def unpivot(self) -> bool:
3578        return bool(self.args.get("unpivot"))
3579
3580
3581class Window(Condition):
3582    arg_types = {
3583        "this": True,
3584        "partition_by": False,
3585        "order": False,
3586        "spec": False,
3587        "alias": False,
3588        "over": False,
3589        "first": False,
3590    }
3591
3592
3593class WindowSpec(Expression):
3594    arg_types = {
3595        "kind": False,
3596        "start": False,
3597        "start_side": False,
3598        "end": False,
3599        "end_side": False,
3600    }
3601
3602
3603class Where(Expression):
3604    pass
3605
3606
3607class Star(Expression):
3608    arg_types = {"except": False, "replace": False}
3609
3610    @property
3611    def name(self) -> str:
3612        return "*"
3613
3614    @property
3615    def output_name(self) -> str:
3616        return self.name
3617
3618
3619class Parameter(Condition):
3620    arg_types = {"this": True, "expression": False}
3621
3622
3623class SessionParameter(Condition):
3624    arg_types = {"this": True, "kind": False}
3625
3626
3627class Placeholder(Condition):
3628    arg_types = {"this": False, "kind": False}
3629
3630
3631class Null(Condition):
3632    arg_types: t.Dict[str, t.Any] = {}
3633
3634    @property
3635    def name(self) -> str:
3636        return "NULL"
3637
3638
3639class Boolean(Condition):
3640    pass
3641
3642
3643class DataTypeParam(Expression):
3644    arg_types = {"this": True, "expression": False}
3645
3646
3647class DataType(Expression):
3648    arg_types = {
3649        "this": True,
3650        "expressions": False,
3651        "nested": False,
3652        "values": False,
3653        "prefix": False,
3654        "kind": False,
3655    }
3656
3657    class Type(AutoName):
3658        ARRAY = auto()
3659        AGGREGATEFUNCTION = auto()
3660        SIMPLEAGGREGATEFUNCTION = auto()
3661        BIGDECIMAL = auto()
3662        BIGINT = auto()
3663        BIGSERIAL = auto()
3664        BINARY = auto()
3665        BIT = auto()
3666        BOOLEAN = auto()
3667        CHAR = auto()
3668        DATE = auto()
3669        DATE32 = auto()
3670        DATEMULTIRANGE = auto()
3671        DATERANGE = auto()
3672        DATETIME = auto()
3673        DATETIME64 = auto()
3674        DECIMAL = auto()
3675        DOUBLE = auto()
3676        ENUM = auto()
3677        ENUM8 = auto()
3678        ENUM16 = auto()
3679        FIXEDSTRING = auto()
3680        FLOAT = auto()
3681        GEOGRAPHY = auto()
3682        GEOMETRY = auto()
3683        HLLSKETCH = auto()
3684        HSTORE = auto()
3685        IMAGE = auto()
3686        INET = auto()
3687        INT = auto()
3688        INT128 = auto()
3689        INT256 = auto()
3690        INT4MULTIRANGE = auto()
3691        INT4RANGE = auto()
3692        INT8MULTIRANGE = auto()
3693        INT8RANGE = auto()
3694        INTERVAL = auto()
3695        IPADDRESS = auto()
3696        IPPREFIX = auto()
3697        IPV4 = auto()
3698        IPV6 = auto()
3699        JSON = auto()
3700        JSONB = auto()
3701        LONGBLOB = auto()
3702        LONGTEXT = auto()
3703        LOWCARDINALITY = auto()
3704        MAP = auto()
3705        MEDIUMBLOB = auto()
3706        MEDIUMINT = auto()
3707        MEDIUMTEXT = auto()
3708        MONEY = auto()
3709        NCHAR = auto()
3710        NESTED = auto()
3711        NULL = auto()
3712        NULLABLE = auto()
3713        NUMMULTIRANGE = auto()
3714        NUMRANGE = auto()
3715        NVARCHAR = auto()
3716        OBJECT = auto()
3717        ROWVERSION = auto()
3718        SERIAL = auto()
3719        SET = auto()
3720        SMALLINT = auto()
3721        SMALLMONEY = auto()
3722        SMALLSERIAL = auto()
3723        STRUCT = auto()
3724        SUPER = auto()
3725        TEXT = auto()
3726        TINYBLOB = auto()
3727        TINYTEXT = auto()
3728        TIME = auto()
3729        TIMETZ = auto()
3730        TIMESTAMP = auto()
3731        TIMESTAMPLTZ = auto()
3732        TIMESTAMPTZ = auto()
3733        TIMESTAMP_S = auto()
3734        TIMESTAMP_MS = auto()
3735        TIMESTAMP_NS = auto()
3736        TINYINT = auto()
3737        TSMULTIRANGE = auto()
3738        TSRANGE = auto()
3739        TSTZMULTIRANGE = auto()
3740        TSTZRANGE = auto()
3741        UBIGINT = auto()
3742        UINT = auto()
3743        UINT128 = auto()
3744        UINT256 = auto()
3745        UMEDIUMINT = auto()
3746        UDECIMAL = auto()
3747        UNIQUEIDENTIFIER = auto()
3748        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3749        USERDEFINED = "USER-DEFINED"
3750        USMALLINT = auto()
3751        UTINYINT = auto()
3752        UUID = auto()
3753        VARBINARY = auto()
3754        VARCHAR = auto()
3755        VARIANT = auto()
3756        XML = auto()
3757        YEAR = auto()
3758
3759    TEXT_TYPES = {
3760        Type.CHAR,
3761        Type.NCHAR,
3762        Type.VARCHAR,
3763        Type.NVARCHAR,
3764        Type.TEXT,
3765    }
3766
3767    INTEGER_TYPES = {
3768        Type.INT,
3769        Type.TINYINT,
3770        Type.SMALLINT,
3771        Type.BIGINT,
3772        Type.INT128,
3773        Type.INT256,
3774        Type.BIT,
3775    }
3776
3777    FLOAT_TYPES = {
3778        Type.FLOAT,
3779        Type.DOUBLE,
3780    }
3781
3782    NUMERIC_TYPES = {
3783        *INTEGER_TYPES,
3784        *FLOAT_TYPES,
3785    }
3786
3787    TEMPORAL_TYPES = {
3788        Type.TIME,
3789        Type.TIMETZ,
3790        Type.TIMESTAMP,
3791        Type.TIMESTAMPTZ,
3792        Type.TIMESTAMPLTZ,
3793        Type.TIMESTAMP_S,
3794        Type.TIMESTAMP_MS,
3795        Type.TIMESTAMP_NS,
3796        Type.DATE,
3797        Type.DATE32,
3798        Type.DATETIME,
3799        Type.DATETIME64,
3800    }
3801
3802    @classmethod
3803    def build(
3804        cls,
3805        dtype: DATA_TYPE,
3806        dialect: DialectType = None,
3807        udt: bool = False,
3808        **kwargs,
3809    ) -> DataType:
3810        """
3811        Constructs a DataType object.
3812
3813        Args:
3814            dtype: the data type of interest.
3815            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3816            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3817                DataType, thus creating a user-defined type.
3818            kawrgs: additional arguments to pass in the constructor of DataType.
3819
3820        Returns:
3821            The constructed DataType object.
3822        """
3823        from sqlglot import parse_one
3824
3825        if isinstance(dtype, str):
3826            if dtype.upper() == "UNKNOWN":
3827                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3828
3829            try:
3830                data_type_exp = parse_one(
3831                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3832                )
3833            except ParseError:
3834                if udt:
3835                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3836                raise
3837        elif isinstance(dtype, DataType.Type):
3838            data_type_exp = DataType(this=dtype)
3839        elif isinstance(dtype, DataType):
3840            return dtype
3841        else:
3842            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3843
3844        return DataType(**{**data_type_exp.args, **kwargs})
3845
3846    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3847        """
3848        Checks whether this DataType matches one of the provided data types. Nested types or precision
3849        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3850
3851        Args:
3852            dtypes: the data types to compare this DataType to.
3853
3854        Returns:
3855            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3856        """
3857        for dtype in dtypes:
3858            other = DataType.build(dtype, udt=True)
3859
3860            if (
3861                other.expressions
3862                or self.this == DataType.Type.USERDEFINED
3863                or other.this == DataType.Type.USERDEFINED
3864            ):
3865                matches = self == other
3866            else:
3867                matches = self.this == other.this
3868
3869            if matches:
3870                return True
3871        return False
3872
3873
3874DATA_TYPE = t.Union[str, DataType, DataType.Type]
3875
3876
3877# https://www.postgresql.org/docs/15/datatype-pseudo.html
3878class PseudoType(DataType):
3879    arg_types = {"this": True}
3880
3881
3882# https://www.postgresql.org/docs/15/datatype-oid.html
3883class ObjectIdentifier(DataType):
3884    arg_types = {"this": True}
3885
3886
3887# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
3888class SubqueryPredicate(Predicate):
3889    pass
3890
3891
3892class All(SubqueryPredicate):
3893    pass
3894
3895
3896class Any(SubqueryPredicate):
3897    pass
3898
3899
3900class Exists(SubqueryPredicate):
3901    pass
3902
3903
3904# Commands to interact with the databases or engines. For most of the command
3905# expressions we parse whatever comes after the command's name as a string.
3906class Command(Expression):
3907    arg_types = {"this": True, "expression": False}
3908
3909
3910class Transaction(Expression):
3911    arg_types = {"this": False, "modes": False, "mark": False}
3912
3913
3914class Commit(Expression):
3915    arg_types = {"chain": False, "this": False, "durability": False}
3916
3917
3918class Rollback(Expression):
3919    arg_types = {"savepoint": False, "this": False}
3920
3921
3922class AlterTable(Expression):
3923    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
3924
3925
3926class AddConstraint(Expression):
3927    arg_types = {"this": False, "expression": False, "enforced": False}
3928
3929
3930class DropPartition(Expression):
3931    arg_types = {"expressions": True, "exists": False}
3932
3933
3934# Binary expressions like (ADD a b)
3935class Binary(Condition):
3936    arg_types = {"this": True, "expression": True}
3937
3938    @property
3939    def left(self) -> Expression:
3940        return self.this
3941
3942    @property
3943    def right(self) -> Expression:
3944        return self.expression
3945
3946
3947class Add(Binary):
3948    pass
3949
3950
3951class Connector(Binary):
3952    pass
3953
3954
3955class And(Connector):
3956    pass
3957
3958
3959class Or(Connector):
3960    pass
3961
3962
3963class BitwiseAnd(Binary):
3964    pass
3965
3966
3967class BitwiseLeftShift(Binary):
3968    pass
3969
3970
3971class BitwiseOr(Binary):
3972    pass
3973
3974
3975class BitwiseRightShift(Binary):
3976    pass
3977
3978
3979class BitwiseXor(Binary):
3980    pass
3981
3982
3983class Div(Binary):
3984    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
3985
3986
3987class Overlaps(Binary):
3988    pass
3989
3990
3991class Dot(Binary):
3992    @property
3993    def name(self) -> str:
3994        return self.expression.name
3995
3996    @property
3997    def output_name(self) -> str:
3998        return self.name
3999
4000    @classmethod
4001    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4002        """Build a Dot object with a sequence of expressions."""
4003        if len(expressions) < 2:
4004            raise ValueError(f"Dot requires >= 2 expressions.")
4005
4006        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4007
4008    @property
4009    def parts(self) -> t.List[Expression]:
4010        """Return the parts of a table / column in order catalog, db, table."""
4011        this, *parts = self.flatten()
4012
4013        parts.reverse()
4014
4015        for arg in ("this", "table", "db", "catalog"):
4016            part = this.args.get(arg)
4017
4018            if isinstance(part, Expression):
4019                parts.append(part)
4020
4021        parts.reverse()
4022        return parts
4023
4024
4025class DPipe(Binary):
4026    arg_types = {"this": True, "expression": True, "safe": False}
4027
4028
4029class EQ(Binary, Predicate):
4030    pass
4031
4032
4033class NullSafeEQ(Binary, Predicate):
4034    pass
4035
4036
4037class NullSafeNEQ(Binary, Predicate):
4038    pass
4039
4040
4041# Represents e.g. := in DuckDB which is mostly used for setting parameters
4042class PropertyEQ(Binary):
4043    pass
4044
4045
4046class Distance(Binary):
4047    pass
4048
4049
4050class Escape(Binary):
4051    pass
4052
4053
4054class Glob(Binary, Predicate):
4055    pass
4056
4057
4058class GT(Binary, Predicate):
4059    pass
4060
4061
4062class GTE(Binary, Predicate):
4063    pass
4064
4065
4066class ILike(Binary, Predicate):
4067    pass
4068
4069
4070class ILikeAny(Binary, Predicate):
4071    pass
4072
4073
4074class IntDiv(Binary):
4075    pass
4076
4077
4078class Is(Binary, Predicate):
4079    pass
4080
4081
4082class Kwarg(Binary):
4083    """Kwarg in special functions like func(kwarg => y)."""
4084
4085
4086class Like(Binary, Predicate):
4087    pass
4088
4089
4090class LikeAny(Binary, Predicate):
4091    pass
4092
4093
4094class LT(Binary, Predicate):
4095    pass
4096
4097
4098class LTE(Binary, Predicate):
4099    pass
4100
4101
4102class Mod(Binary):
4103    pass
4104
4105
4106class Mul(Binary):
4107    pass
4108
4109
4110class NEQ(Binary, Predicate):
4111    pass
4112
4113
4114# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
4115class Operator(Binary):
4116    arg_types = {"this": True, "operator": True, "expression": True}
4117
4118
4119class SimilarTo(Binary, Predicate):
4120    pass
4121
4122
4123class Slice(Binary):
4124    arg_types = {"this": False, "expression": False}
4125
4126
4127class Sub(Binary):
4128    pass
4129
4130
4131class ArrayOverlaps(Binary):
4132    pass
4133
4134
4135# Unary Expressions
4136# (NOT a)
4137class Unary(Condition):
4138    pass
4139
4140
4141class BitwiseNot(Unary):
4142    pass
4143
4144
4145class Not(Unary):
4146    pass
4147
4148
4149class Paren(Unary):
4150    arg_types = {"this": True, "with": False}
4151
4152    @property
4153    def output_name(self) -> str:
4154        return self.this.name
4155
4156
4157class Neg(Unary):
4158    pass
4159
4160
4161class Alias(Expression):
4162    arg_types = {"this": True, "alias": False}
4163
4164    @property
4165    def output_name(self) -> str:
4166        return self.alias
4167
4168
4169# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
4170# other dialects require identifiers. This enables us to transpile between them easily.
4171class PivotAlias(Alias):
4172    pass
4173
4174
4175class Aliases(Expression):
4176    arg_types = {"this": True, "expressions": True}
4177
4178    @property
4179    def aliases(self):
4180        return self.expressions
4181
4182
4183# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
4184class AtIndex(Expression):
4185    arg_types = {"this": True, "expression": True}
4186
4187
4188class AtTimeZone(Expression):
4189    arg_types = {"this": True, "zone": True}
4190
4191
4192class FromTimeZone(Expression):
4193    arg_types = {"this": True, "zone": True}
4194
4195
4196class Between(Predicate):
4197    arg_types = {"this": True, "low": True, "high": True}
4198
4199
4200class Bracket(Condition):
4201    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4202    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4203
4204    @property
4205    def output_name(self) -> str:
4206        if len(self.expressions) == 1:
4207            return self.expressions[0].output_name
4208
4209        return super().output_name
4210
4211
4212class Distinct(Expression):
4213    arg_types = {"expressions": False, "on": False}
4214
4215
4216class In(Predicate):
4217    arg_types = {
4218        "this": True,
4219        "expressions": False,
4220        "query": False,
4221        "unnest": False,
4222        "field": False,
4223        "is_global": False,
4224    }
4225
4226
4227# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
4228class ForIn(Expression):
4229    arg_types = {"this": True, "expression": True}
4230
4231
4232class TimeUnit(Expression):
4233    """Automatically converts unit arg into a var."""
4234
4235    arg_types = {"unit": False}
4236
4237    UNABBREVIATED_UNIT_NAME = {
4238        "D": "DAY",
4239        "H": "HOUR",
4240        "M": "MINUTE",
4241        "MS": "MILLISECOND",
4242        "NS": "NANOSECOND",
4243        "Q": "QUARTER",
4244        "S": "SECOND",
4245        "US": "MICROSECOND",
4246        "W": "WEEK",
4247        "Y": "YEAR",
4248    }
4249
4250    VAR_LIKE = (Column, Literal, Var)
4251
4252    def __init__(self, **args):
4253        unit = args.get("unit")
4254        if isinstance(unit, self.VAR_LIKE):
4255            args["unit"] = Var(
4256                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4257            )
4258        elif isinstance(unit, Week):
4259            unit.set("this", Var(this=unit.this.name.upper()))
4260
4261        super().__init__(**args)
4262
4263    @property
4264    def unit(self) -> t.Optional[Var]:
4265        return self.args.get("unit")
4266
4267
4268class IntervalOp(TimeUnit):
4269    arg_types = {"unit": True, "expression": True}
4270
4271    def interval(self):
4272        return Interval(
4273            this=self.expression.copy(),
4274            unit=self.unit.copy(),
4275        )
4276
4277
4278# https://www.oracletutorial.com/oracle-basics/oracle-interval/
4279# https://trino.io/docs/current/language/types.html#interval-day-to-second
4280# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
4281class IntervalSpan(DataType):
4282    arg_types = {"this": True, "expression": True}
4283
4284
4285class Interval(TimeUnit):
4286    arg_types = {"this": False, "unit": False}
4287
4288
4289class IgnoreNulls(Expression):
4290    pass
4291
4292
4293class RespectNulls(Expression):
4294    pass
4295
4296
4297# Functions
4298class Func(Condition):
4299    """
4300    The base class for all function expressions.
4301
4302    Attributes:
4303        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4304            treated as a variable length argument and the argument's value will be stored as a list.
4305        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4306            for this function expression. These values are used to map this node to a name during parsing
4307            as well as to provide the function's name during SQL string generation. By default the SQL
4308            name is set to the expression's class name transformed to snake case.
4309    """
4310
4311    is_var_len_args = False
4312
4313    @classmethod
4314    def from_arg_list(cls, args):
4315        if cls.is_var_len_args:
4316            all_arg_keys = list(cls.arg_types)
4317            # If this function supports variable length argument treat the last argument as such.
4318            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4319            num_non_var = len(non_var_len_arg_keys)
4320
4321            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4322            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4323        else:
4324            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4325
4326        return cls(**args_dict)
4327
4328    @classmethod
4329    def sql_names(cls):
4330        if cls is Func:
4331            raise NotImplementedError(
4332                "SQL name is only supported by concrete function implementations"
4333            )
4334        if "_sql_names" not in cls.__dict__:
4335            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4336        return cls._sql_names
4337
4338    @classmethod
4339    def sql_name(cls):
4340        return cls.sql_names()[0]
4341
4342    @classmethod
4343    def default_parser_mappings(cls):
4344        return {name: cls.from_arg_list for name in cls.sql_names()}
4345
4346
4347class AggFunc(Func):
4348    pass
4349
4350
4351class ParameterizedAgg(AggFunc):
4352    arg_types = {"this": True, "expressions": True, "params": True}
4353
4354
4355class Abs(Func):
4356    pass
4357
4358
4359class ArgMax(AggFunc):
4360    arg_types = {"this": True, "expression": True, "count": False}
4361    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
4362
4363
4364class ArgMin(AggFunc):
4365    arg_types = {"this": True, "expression": True, "count": False}
4366    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
4367
4368
4369class ApproxTopK(AggFunc):
4370    arg_types = {"this": True, "expression": False, "counters": False}
4371
4372
4373class Flatten(Func):
4374    pass
4375
4376
4377# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4378class Transform(Func):
4379    arg_types = {"this": True, "expression": True}
4380
4381
4382class Anonymous(Func):
4383    arg_types = {"this": True, "expressions": False}
4384    is_var_len_args = True
4385
4386
4387class AnonymousAggFunc(AggFunc):
4388    arg_types = {"this": True, "expressions": False}
4389    is_var_len_args = True
4390
4391
4392# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
4393class CombinedAggFunc(AnonymousAggFunc):
4394    arg_types = {"this": True, "expressions": False, "parts": True}
4395
4396
4397class CombinedParameterizedAgg(ParameterizedAgg):
4398    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
4399
4400
4401# https://docs.snowflake.com/en/sql-reference/functions/hll
4402# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4403class Hll(AggFunc):
4404    arg_types = {"this": True, "expressions": False}
4405    is_var_len_args = True
4406
4407
4408class ApproxDistinct(AggFunc):
4409    arg_types = {"this": True, "accuracy": False}
4410    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4411
4412
4413class Array(Func):
4414    arg_types = {"expressions": False}
4415    is_var_len_args = True
4416
4417
4418# https://docs.snowflake.com/en/sql-reference/functions/to_array
4419class ToArray(Func):
4420    pass
4421
4422
4423# https://docs.snowflake.com/en/sql-reference/functions/to_char
4424# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
4425class ToChar(Func):
4426    arg_types = {"this": True, "format": False, "nlsparam": False}
4427
4428
4429class GenerateSeries(Func):
4430    arg_types = {"start": True, "end": True, "step": False}
4431
4432
4433class ArrayAgg(AggFunc):
4434    pass
4435
4436
4437class ArrayUniqueAgg(AggFunc):
4438    pass
4439
4440
4441class ArrayAll(Func):
4442    arg_types = {"this": True, "expression": True}
4443
4444
4445class ArrayAny(Func):
4446    arg_types = {"this": True, "expression": True}
4447
4448
4449class ArrayConcat(Func):
4450    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4451    arg_types = {"this": True, "expressions": False}
4452    is_var_len_args = True
4453
4454
4455class ArrayContains(Binary, Func):
4456    pass
4457
4458
4459class ArrayContained(Binary):
4460    pass
4461
4462
4463class ArrayFilter(Func):
4464    arg_types = {"this": True, "expression": True}
4465    _sql_names = ["FILTER", "ARRAY_FILTER"]
4466
4467
4468class ArrayJoin(Func):
4469    arg_types = {"this": True, "expression": True, "null": False}
4470
4471
4472class ArraySize(Func):
4473    arg_types = {"this": True, "expression": False}
4474
4475
4476class ArraySort(Func):
4477    arg_types = {"this": True, "expression": False}
4478
4479
4480class ArraySum(Func):
4481    arg_types = {"this": True, "expression": False}
4482
4483
4484class ArrayUnionAgg(AggFunc):
4485    pass
4486
4487
4488class Avg(AggFunc):
4489    pass
4490
4491
4492class AnyValue(AggFunc):
4493    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
4494
4495
4496class First(Func):
4497    arg_types = {"this": True, "ignore_nulls": False}
4498
4499
4500class Last(Func):
4501    arg_types = {"this": True, "ignore_nulls": False}
4502
4503
4504class Case(Func):
4505    arg_types = {"this": False, "ifs": True, "default": False}
4506
4507    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4508        instance = maybe_copy(self, copy)
4509        instance.append(
4510            "ifs",
4511            If(
4512                this=maybe_parse(condition, copy=copy, **opts),
4513                true=maybe_parse(then, copy=copy, **opts),
4514            ),
4515        )
4516        return instance
4517
4518    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4519        instance = maybe_copy(self, copy)
4520        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4521        return instance
4522
4523
4524class Cast(Func):
4525    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4526
4527    @property
4528    def name(self) -> str:
4529        return self.this.name
4530
4531    @property
4532    def to(self) -> DataType:
4533        return self.args["to"]
4534
4535    @property
4536    def output_name(self) -> str:
4537        return self.name
4538
4539    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4540        """
4541        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4542        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4543        array<int> != array<float>.
4544
4545        Args:
4546            dtypes: the data types to compare this Cast's DataType to.
4547
4548        Returns:
4549            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4550        """
4551        return self.to.is_type(*dtypes)
4552
4553
4554class TryCast(Cast):
4555    pass
4556
4557
4558class CastToStrType(Func):
4559    arg_types = {"this": True, "to": True}
4560
4561
4562class Collate(Binary, Func):
4563    pass
4564
4565
4566class Ceil(Func):
4567    arg_types = {"this": True, "decimals": False}
4568    _sql_names = ["CEIL", "CEILING"]
4569
4570
4571class Coalesce(Func):
4572    arg_types = {"this": True, "expressions": False}
4573    is_var_len_args = True
4574    _sql_names = ["COALESCE", "IFNULL", "NVL"]
4575
4576
4577class Chr(Func):
4578    arg_types = {"this": True, "charset": False, "expressions": False}
4579    is_var_len_args = True
4580    _sql_names = ["CHR", "CHAR"]
4581
4582
4583class Concat(Func):
4584    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4585    is_var_len_args = True
4586
4587
4588class ConcatWs(Concat):
4589    _sql_names = ["CONCAT_WS"]
4590
4591
4592class Count(AggFunc):
4593    arg_types = {"this": False, "expressions": False}
4594    is_var_len_args = True
4595
4596
4597class CountIf(AggFunc):
4598    _sql_names = ["COUNT_IF", "COUNTIF"]
4599
4600
4601class CurrentDate(Func):
4602    arg_types = {"this": False}
4603
4604
4605class CurrentDatetime(Func):
4606    arg_types = {"this": False}
4607
4608
4609class CurrentTime(Func):
4610    arg_types = {"this": False}
4611
4612
4613class CurrentTimestamp(Func):
4614    arg_types = {"this": False}
4615
4616
4617class CurrentUser(Func):
4618    arg_types = {"this": False}
4619
4620
4621class DateAdd(Func, IntervalOp):
4622    arg_types = {"this": True, "expression": True, "unit": False}
4623
4624
4625class DateSub(Func, IntervalOp):
4626    arg_types = {"this": True, "expression": True, "unit": False}
4627
4628
4629class DateDiff(Func, TimeUnit):
4630    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4631    arg_types = {"this": True, "expression": True, "unit": False}
4632
4633
4634class DateTrunc(Func):
4635    arg_types = {"unit": True, "this": True, "zone": False}
4636
4637    def __init__(self, **args):
4638        unit = args.get("unit")
4639        if isinstance(unit, TimeUnit.VAR_LIKE):
4640            args["unit"] = Literal.string(
4641                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4642            )
4643        elif isinstance(unit, Week):
4644            unit.set("this", Literal.string(unit.this.name.upper()))
4645
4646        super().__init__(**args)
4647
4648    @property
4649    def unit(self) -> Expression:
4650        return self.args["unit"]
4651
4652
4653class DatetimeAdd(Func, IntervalOp):
4654    arg_types = {"this": True, "expression": True, "unit": False}
4655
4656
4657class DatetimeSub(Func, IntervalOp):
4658    arg_types = {"this": True, "expression": True, "unit": False}
4659
4660
4661class DatetimeDiff(Func, TimeUnit):
4662    arg_types = {"this": True, "expression": True, "unit": False}
4663
4664
4665class DatetimeTrunc(Func, TimeUnit):
4666    arg_types = {"this": True, "unit": True, "zone": False}
4667
4668
4669class DayOfWeek(Func):
4670    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
4671
4672
4673class DayOfMonth(Func):
4674    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
4675
4676
4677class DayOfYear(Func):
4678    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
4679
4680
4681class ToDays(Func):
4682    pass
4683
4684
4685class WeekOfYear(Func):
4686    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
4687
4688
4689class MonthsBetween(Func):
4690    arg_types = {"this": True, "expression": True, "roundoff": False}
4691
4692
4693class LastDay(Func, TimeUnit):
4694    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4695    arg_types = {"this": True, "unit": False}
4696
4697
4698class Extract(Func):
4699    arg_types = {"this": True, "expression": True}
4700
4701
4702class Timestamp(Func):
4703    arg_types = {"this": False, "expression": False}
4704
4705
4706class TimestampAdd(Func, TimeUnit):
4707    arg_types = {"this": True, "expression": True, "unit": False}
4708
4709
4710class TimestampSub(Func, TimeUnit):
4711    arg_types = {"this": True, "expression": True, "unit": False}
4712
4713
4714class TimestampDiff(Func, TimeUnit):
4715    arg_types = {"this": True, "expression": True, "unit": False}
4716
4717
4718class TimestampTrunc(Func, TimeUnit):
4719    arg_types = {"this": True, "unit": True, "zone": False}
4720
4721
4722class TimeAdd(Func, TimeUnit):
4723    arg_types = {"this": True, "expression": True, "unit": False}
4724
4725
4726class TimeSub(Func, TimeUnit):
4727    arg_types = {"this": True, "expression": True, "unit": False}
4728
4729
4730class TimeDiff(Func, TimeUnit):
4731    arg_types = {"this": True, "expression": True, "unit": False}
4732
4733
4734class TimeTrunc(Func, TimeUnit):
4735    arg_types = {"this": True, "unit": True, "zone": False}
4736
4737
4738class DateFromParts(Func):
4739    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4740    arg_types = {"year": True, "month": True, "day": True}
4741
4742
4743class TimeFromParts(Func):
4744    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4745    arg_types = {
4746        "hour": True,
4747        "min": True,
4748        "sec": True,
4749        "nano": False,
4750        "fractions": False,
4751        "precision": False,
4752    }
4753
4754
4755class DateStrToDate(Func):
4756    pass
4757
4758
4759class DateToDateStr(Func):
4760    pass
4761
4762
4763class DateToDi(Func):
4764    pass
4765
4766
4767# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
4768class Date(Func):
4769    arg_types = {"this": False, "zone": False, "expressions": False}
4770    is_var_len_args = True
4771
4772
4773class Day(Func):
4774    pass
4775
4776
4777class Decode(Func):
4778    arg_types = {"this": True, "charset": True, "replace": False}
4779
4780
4781class DiToDate(Func):
4782    pass
4783
4784
4785class Encode(Func):
4786    arg_types = {"this": True, "charset": True}
4787
4788
4789class Exp(Func):
4790    pass
4791
4792
4793# https://docs.snowflake.com/en/sql-reference/functions/flatten
4794class Explode(Func):
4795    arg_types = {"this": True, "expressions": False}
4796    is_var_len_args = True
4797
4798
4799class ExplodeOuter(Explode):
4800    pass
4801
4802
4803class Posexplode(Explode):
4804    pass
4805
4806
4807class PosexplodeOuter(Posexplode):
4808    pass
4809
4810
4811class Floor(Func):
4812    arg_types = {"this": True, "decimals": False}
4813
4814
4815class FromBase64(Func):
4816    pass
4817
4818
4819class ToBase64(Func):
4820    pass
4821
4822
4823class Greatest(Func):
4824    arg_types = {"this": True, "expressions": False}
4825    is_var_len_args = True
4826
4827
4828class GroupConcat(AggFunc):
4829    arg_types = {"this": True, "separator": False}
4830
4831
4832class Hex(Func):
4833    pass
4834
4835
4836class Xor(Connector, Func):
4837    arg_types = {"this": False, "expression": False, "expressions": False}
4838
4839
4840class If(Func):
4841    arg_types = {"this": True, "true": True, "false": False}
4842
4843
4844class Nullif(Func):
4845    arg_types = {"this": True, "expression": True}
4846
4847
4848class Initcap(Func):
4849    arg_types = {"this": True, "expression": False}
4850
4851
4852class IsNan(Func):
4853    _sql_names = ["IS_NAN", "ISNAN"]
4854
4855
4856class IsInf(Func):
4857    _sql_names = ["IS_INF", "ISINF"]
4858
4859
4860class FormatJson(Expression):
4861    pass
4862
4863
4864class JSONKeyValue(Expression):
4865    arg_types = {"this": True, "expression": True}
4866
4867
4868class JSONObject(Func):
4869    arg_types = {
4870        "expressions": False,
4871        "null_handling": False,
4872        "unique_keys": False,
4873        "return_type": False,
4874        "encoding": False,
4875    }
4876
4877
4878class JSONObjectAgg(AggFunc):
4879    arg_types = {
4880        "expressions": False,
4881        "null_handling": False,
4882        "unique_keys": False,
4883        "return_type": False,
4884        "encoding": False,
4885    }
4886
4887
4888# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
4889class JSONArray(Func):
4890    arg_types = {
4891        "expressions": True,
4892        "null_handling": False,
4893        "return_type": False,
4894        "strict": False,
4895    }
4896
4897
4898# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
4899class JSONArrayAgg(Func):
4900    arg_types = {
4901        "this": True,
4902        "order": False,
4903        "null_handling": False,
4904        "return_type": False,
4905        "strict": False,
4906    }
4907
4908
4909# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4910# Note: parsing of JSON column definitions is currently incomplete.
4911class JSONColumnDef(Expression):
4912    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
4913
4914
4915class JSONSchema(Expression):
4916    arg_types = {"expressions": True}
4917
4918
4919# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4920class JSONTable(Func):
4921    arg_types = {
4922        "this": True,
4923        "schema": True,
4924        "path": False,
4925        "error_handling": False,
4926        "empty_handling": False,
4927    }
4928
4929
4930class OpenJSONColumnDef(Expression):
4931    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
4932
4933
4934class OpenJSON(Func):
4935    arg_types = {"this": True, "path": False, "expressions": False}
4936
4937
4938class JSONBContains(Binary):
4939    _sql_names = ["JSONB_CONTAINS"]
4940
4941
4942class JSONExtract(Binary, Func):
4943    _sql_names = ["JSON_EXTRACT"]
4944
4945
4946class JSONExtractScalar(JSONExtract):
4947    _sql_names = ["JSON_EXTRACT_SCALAR"]
4948
4949
4950class JSONBExtract(JSONExtract):
4951    _sql_names = ["JSONB_EXTRACT"]
4952
4953
4954class JSONBExtractScalar(JSONExtract):
4955    _sql_names = ["JSONB_EXTRACT_SCALAR"]
4956
4957
4958class JSONFormat(Func):
4959    arg_types = {"this": False, "options": False}
4960    _sql_names = ["JSON_FORMAT"]
4961
4962
4963# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
4964class JSONArrayContains(Binary, Predicate, Func):
4965    _sql_names = ["JSON_ARRAY_CONTAINS"]
4966
4967
4968class ParseJSON(Func):
4969    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4970    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4971    arg_types = {"this": True, "expressions": False}
4972    is_var_len_args = True
4973
4974
4975# https://docs.snowflake.com/en/sql-reference/functions/get_path
4976class GetPath(Func):
4977    arg_types = {"this": True, "expression": True}
4978
4979    @property
4980    def output_name(self) -> str:
4981        return self.expression.output_name
4982
4983
4984class Least(Func):
4985    arg_types = {"this": True, "expressions": False}
4986    is_var_len_args = True
4987
4988
4989class Left(Func):
4990    arg_types = {"this": True, "expression": True}
4991
4992
4993class Right(Func):
4994    arg_types = {"this": True, "expression": True}
4995
4996
4997class Length(Func):
4998    _sql_names = ["LENGTH", "LEN"]
4999
5000
5001class Levenshtein(Func):
5002    arg_types = {
5003        "this": True,
5004        "expression": False,
5005        "ins_cost": False,
5006        "del_cost": False,
5007        "sub_cost": False,
5008    }
5009
5010
5011class Ln(Func):
5012    pass
5013
5014
5015class Log(Func):
5016    arg_types = {"this": True, "expression": False}
5017
5018
5019class Log2(Func):
5020    pass
5021
5022
5023class Log10(Func):
5024    pass
5025
5026
5027class LogicalOr(AggFunc):
5028    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
5029
5030
5031class LogicalAnd(AggFunc):
5032    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
5033
5034
5035class Lower(Func):
5036    _sql_names = ["LOWER", "LCASE"]
5037
5038
5039class Map(Func):
5040    arg_types = {"keys": False, "values": False}
5041
5042    @property
5043    def keys(self) -> t.List[Expression]:
5044        keys = self.args.get("keys")
5045        return keys.expressions if keys else []
5046
5047    @property
5048    def values(self) -> t.List[Expression]:
5049        values = self.args.get("values")
5050        return values.expressions if values else []
5051
5052
5053class MapFromEntries(Func):
5054    pass
5055
5056
5057class StarMap(Func):
5058    pass
5059
5060
5061class VarMap(Func):
5062    arg_types = {"keys": True, "values": True}
5063    is_var_len_args = True
5064
5065    @property
5066    def keys(self) -> t.List[Expression]:
5067        return self.args["keys"].expressions
5068
5069    @property
5070    def values(self) -> t.List[Expression]:
5071        return self.args["values"].expressions
5072
5073
5074# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
5075class MatchAgainst(Func):
5076    arg_types = {"this": True, "expressions": True, "modifier": False}
5077
5078
5079class Max(AggFunc):
5080    arg_types = {"this": True, "expressions": False}
5081    is_var_len_args = True
5082
5083
5084class MD5(Func):
5085    _sql_names = ["MD5"]
5086
5087
5088# Represents the variant of the MD5 function that returns a binary value
5089class MD5Digest(Func):
5090    _sql_names = ["MD5_DIGEST"]
5091
5092
5093class Min(AggFunc):
5094    arg_types = {"this": True, "expressions": False}
5095    is_var_len_args = True
5096
5097
5098class Month(Func):
5099    pass
5100
5101
5102class Nvl2(Func):
5103    arg_types = {"this": True, "true": True, "false": False}
5104
5105
5106# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5107class Predict(Func):
5108    arg_types = {"this": True, "expression": True, "params_struct": False}
5109
5110
5111class Pow(Binary, Func):
5112    _sql_names = ["POWER", "POW"]
5113
5114
5115class PercentileCont(AggFunc):
5116    arg_types = {"this": True, "expression": False}
5117
5118
5119class PercentileDisc(AggFunc):
5120    arg_types = {"this": True, "expression": False}
5121
5122
5123class Quantile(AggFunc):
5124    arg_types = {"this": True, "quantile": True}
5125
5126
5127class ApproxQuantile(Quantile):
5128    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5129
5130
5131class Rand(Func):
5132    _sql_names = ["RAND", "RANDOM"]
5133    arg_types = {"this": False}
5134
5135
5136class Randn(Func):
5137    arg_types = {"this": False}
5138
5139
5140class RangeN(Func):
5141    arg_types = {"this": True, "expressions": True, "each": False}
5142
5143
5144class ReadCSV(Func):
5145    _sql_names = ["READ_CSV"]
5146    is_var_len_args = True
5147    arg_types = {"this": True, "expressions": False}
5148
5149
5150class Reduce(Func):
5151    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5152
5153
5154class RegexpExtract(Func):
5155    arg_types = {
5156        "this": True,
5157        "expression": True,
5158        "position": False,
5159        "occurrence": False,
5160        "parameters": False,
5161        "group": False,
5162    }
5163
5164
5165class RegexpReplace(Func):
5166    arg_types = {
5167        "this": True,
5168        "expression": True,
5169        "replacement": False,
5170        "position": False,
5171        "occurrence": False,
5172        "parameters": False,
5173        "modifiers": False,
5174    }
5175
5176
5177class RegexpLike(Binary, Func):
5178    arg_types = {"this": True, "expression": True, "flag": False}
5179
5180
5181class RegexpILike(Binary, Func):
5182    arg_types = {"this": True, "expression": True, "flag": False}
5183
5184
5185# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5186# limit is the number of times a pattern is applied
5187class RegexpSplit(Func):
5188    arg_types = {"this": True, "expression": True, "limit": False}
5189
5190
5191class Repeat(Func):
5192    arg_types = {"this": True, "times": True}
5193
5194
5195# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
5196# tsql third argument function == trunctaion if not 0
5197class Round(Func):
5198    arg_types = {"this": True, "decimals": False, "truncate": False}
5199
5200
5201class RowNumber(Func):
5202    arg_types: t.Dict[str, t.Any] = {}
5203
5204
5205class SafeDivide(Func):
5206    arg_types = {"this": True, "expression": True}
5207
5208
5209class SHA(Func):
5210    _sql_names = ["SHA", "SHA1"]
5211
5212
5213class SHA2(Func):
5214    _sql_names = ["SHA2"]
5215    arg_types = {"this": True, "length": False}
5216
5217
5218class SortArray(Func):
5219    arg_types = {"this": True, "asc": False}
5220
5221
5222class Split(Func):
5223    arg_types = {"this": True, "expression": True, "limit": False}
5224
5225
5226# Start may be omitted in the case of postgres
5227# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5228class Substring(Func):
5229    arg_types = {"this": True, "start": False, "length": False}
5230
5231
5232class StandardHash(Func):
5233    arg_types = {"this": True, "expression": False}
5234
5235
5236class StartsWith(Func):
5237    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5238    arg_types = {"this": True, "expression": True}
5239
5240
5241class StrPosition(Func):
5242    arg_types = {
5243        "this": True,
5244        "substr": True,
5245        "position": False,
5246        "instance": False,
5247    }
5248
5249
5250class StrToDate(Func):
5251    arg_types = {"this": True, "format": True}
5252
5253
5254class StrToTime(Func):
5255    arg_types = {"this": True, "format": True, "zone": False}
5256
5257
5258# Spark allows unix_timestamp()
5259# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5260class StrToUnix(Func):
5261    arg_types = {"this": False, "format": False}
5262
5263
5264# https://prestodb.io/docs/current/functions/string.html
5265# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5266class StrToMap(Func):
5267    arg_types = {
5268        "this": True,
5269        "pair_delim": False,
5270        "key_value_delim": False,
5271        "duplicate_resolution_callback": False,
5272    }
5273
5274
5275class NumberToStr(Func):
5276    arg_types = {"this": True, "format": True, "culture": False}
5277
5278
5279class FromBase(Func):
5280    arg_types = {"this": True, "expression": True}
5281
5282
5283class Struct(Func):
5284    arg_types = {"expressions": False}
5285    is_var_len_args = True
5286
5287
5288class StructExtract(Func):
5289    arg_types = {"this": True, "expression": True}
5290
5291
5292# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5293# https://docs.snowflake.com/en/sql-reference/functions/insert
5294class Stuff(Func):
5295    _sql_names = ["STUFF", "INSERT"]
5296    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5297
5298
5299class Sum(AggFunc):
5300    pass
5301
5302
5303class Sqrt(Func):
5304    pass
5305
5306
5307class Stddev(AggFunc):
5308    pass
5309
5310
5311class StddevPop(AggFunc):
5312    pass
5313
5314
5315class StddevSamp(AggFunc):
5316    pass
5317
5318
5319class TimeToStr(Func):
5320    arg_types = {"this": True, "format": True, "culture": False}
5321
5322
5323class TimeToTimeStr(Func):
5324    pass
5325
5326
5327class TimeToUnix(Func):
5328    pass
5329
5330
5331class TimeStrToDate(Func):
5332    pass
5333
5334
5335class TimeStrToTime(Func):
5336    pass
5337
5338
5339class TimeStrToUnix(Func):
5340    pass
5341
5342
5343class Trim(Func):
5344    arg_types = {
5345        "this": True,
5346        "expression": False,
5347        "position": False,
5348        "collation": False,
5349    }
5350
5351
5352class TsOrDsAdd(Func, TimeUnit):
5353    # return_type is used to correctly cast the arguments of this expression when transpiling it
5354    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5355
5356    @property
5357    def return_type(self) -> DataType:
5358        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5359
5360
5361class TsOrDsDiff(Func, TimeUnit):
5362    arg_types = {"this": True, "expression": True, "unit": False}
5363
5364
5365class TsOrDsToDateStr(Func):
5366    pass
5367
5368
5369class TsOrDsToDate(Func):
5370    arg_types = {"this": True, "format": False}
5371
5372
5373class TsOrDsToTime(Func):
5374    pass
5375
5376
5377class TsOrDiToDi(Func):
5378    pass
5379
5380
5381class Unhex(Func):
5382    pass
5383
5384
5385# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
5386class UnixDate(Func):
5387    pass
5388
5389
5390class UnixToStr(Func):
5391    arg_types = {"this": True, "format": False}
5392
5393
5394# https://prestodb.io/docs/current/functions/datetime.html
5395# presto has weird zone/hours/minutes
5396class UnixToTime(Func):
5397    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5398
5399    SECONDS = Literal.number(0)
5400    DECIS = Literal.number(1)
5401    CENTIS = Literal.number(2)
5402    MILLIS = Literal.number(3)
5403    DECIMILLIS = Literal.number(4)
5404    CENTIMILLIS = Literal.number(5)
5405    MICROS = Literal.number(6)
5406    DECIMICROS = Literal.number(7)
5407    CENTIMICROS = Literal.number(8)
5408    NANOS = Literal.number(9)
5409
5410
5411class UnixToTimeStr(Func):
5412    pass
5413
5414
5415class TimestampFromParts(Func):
5416    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5417    arg_types = {
5418        "year": True,
5419        "month": True,
5420        "day": True,
5421        "hour": True,
5422        "min": True,
5423        "sec": True,
5424        "nano": False,
5425        "zone": False,
5426        "milli": False,
5427    }
5428
5429
5430class Upper(Func):
5431    _sql_names = ["UPPER", "UCASE"]
5432
5433
5434class Variance(AggFunc):
5435    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5436
5437
5438class VariancePop(AggFunc):
5439    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5440
5441
5442class Week(Func):
5443    arg_types = {"this": True, "mode": False}
5444
5445
5446class XMLTable(Func):
5447    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5448
5449
5450class Year(Func):
5451    pass
5452
5453
5454class Use(Expression):
5455    arg_types = {"this": True, "kind": False}
5456
5457
5458class Merge(Expression):
5459    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
5460
5461
5462class When(Func):
5463    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5464
5465
5466# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5467# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5468class NextValueFor(Func):
5469    arg_types = {"this": True, "order": False}
5470
5471
5472def _norm_arg(arg):
5473    return arg.lower() if type(arg) is str else arg
5474
5475
5476ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5477FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
5478
5479
5480# Helpers
5481@t.overload
5482def maybe_parse(
5483    sql_or_expression: ExpOrStr,
5484    *,
5485    into: t.Type[E],
5486    dialect: DialectType = None,
5487    prefix: t.Optional[str] = None,
5488    copy: bool = False,
5489    **opts,
5490) -> E: ...
5491
5492
5493@t.overload
5494def maybe_parse(
5495    sql_or_expression: str | E,
5496    *,
5497    into: t.Optional[IntoType] = None,
5498    dialect: DialectType = None,
5499    prefix: t.Optional[str] = None,
5500    copy: bool = False,
5501    **opts,
5502) -> E: ...
5503
5504
5505def maybe_parse(
5506    sql_or_expression: ExpOrStr,
5507    *,
5508    into: t.Optional[IntoType] = None,
5509    dialect: DialectType = None,
5510    prefix: t.Optional[str] = None,
5511    copy: bool = False,
5512    **opts,
5513) -> Expression:
5514    """Gracefully handle a possible string or expression.
5515
5516    Example:
5517        >>> maybe_parse("1")
5518        Literal(this=1, is_string=False)
5519        >>> maybe_parse(to_identifier("x"))
5520        Identifier(this=x, quoted=False)
5521
5522    Args:
5523        sql_or_expression: the SQL code string or an expression
5524        into: the SQLGlot Expression to parse into
5525        dialect: the dialect used to parse the input expressions (in the case that an
5526            input expression is a SQL string).
5527        prefix: a string to prefix the sql with before it gets parsed
5528            (automatically includes a space)
5529        copy: whether or not to copy the expression.
5530        **opts: other options to use to parse the input expressions (again, in the case
5531            that an input expression is a SQL string).
5532
5533    Returns:
5534        Expression: the parsed or given expression.
5535    """
5536    if isinstance(sql_or_expression, Expression):
5537        if copy:
5538            return sql_or_expression.copy()
5539        return sql_or_expression
5540
5541    if sql_or_expression is None:
5542        raise ParseError(f"SQL cannot be None")
5543
5544    import sqlglot
5545
5546    sql = str(sql_or_expression)
5547    if prefix:
5548        sql = f"{prefix} {sql}"
5549
5550    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5551
5552
5553@t.overload
5554def maybe_copy(instance: None, copy: bool = True) -> None: ...
5555
5556
5557@t.overload
5558def maybe_copy(instance: E, copy: bool = True) -> E: ...
5559
5560
5561def maybe_copy(instance, copy=True):
5562    return instance.copy() if copy and instance else instance
5563
5564
5565def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
5566    """Generate a textual representation of an Expression tree"""
5567    indent = "\n" + ("  " * (level + 1))
5568    delim = f",{indent}"
5569
5570    if isinstance(node, Expression):
5571        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
5572
5573        if (node.type or verbose) and not isinstance(node, DataType):
5574            args["_type"] = node.type
5575        if node.comments or verbose:
5576            args["_comments"] = node.comments
5577
5578        if verbose:
5579            args["_id"] = id(node)
5580
5581        # Inline leaves for a more compact representation
5582        if node.is_leaf():
5583            indent = ""
5584            delim = ", "
5585
5586        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
5587        return f"{node.__class__.__name__}({indent}{items})"
5588
5589    if isinstance(node, list):
5590        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
5591        items = f"{indent}{items}" if items else ""
5592        return f"[{items}]"
5593
5594    # Indent multiline strings to match the current level
5595    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
5596
5597
5598def _is_wrong_expression(expression, into):
5599    return isinstance(expression, Expression) and not isinstance(expression, into)
5600
5601
5602def _apply_builder(
5603    expression,
5604    instance,
5605    arg,
5606    copy=True,
5607    prefix=None,
5608    into=None,
5609    dialect=None,
5610    into_arg="this",
5611    **opts,
5612):
5613    if _is_wrong_expression(expression, into):
5614        expression = into(**{into_arg: expression})
5615    instance = maybe_copy(instance, copy)
5616    expression = maybe_parse(
5617        sql_or_expression=expression,
5618        prefix=prefix,
5619        into=into,
5620        dialect=dialect,
5621        **opts,
5622    )
5623    instance.set(arg, expression)
5624    return instance
5625
5626
5627def _apply_child_list_builder(
5628    *expressions,
5629    instance,
5630    arg,
5631    append=True,
5632    copy=True,
5633    prefix=None,
5634    into=None,
5635    dialect=None,
5636    properties=None,
5637    **opts,
5638):
5639    instance = maybe_copy(instance, copy)
5640    parsed = []
5641    for expression in expressions:
5642        if expression is not None:
5643            if _is_wrong_expression(expression, into):
5644                expression = into(expressions=[expression])
5645
5646            expression = maybe_parse(
5647                expression,
5648                into=into,
5649                dialect=dialect,
5650                prefix=prefix,
5651                **opts,
5652            )
5653            parsed.extend(expression.expressions)
5654
5655    existing = instance.args.get(arg)
5656    if append and existing:
5657        parsed = existing.expressions + parsed
5658
5659    child = into(expressions=parsed)
5660    for k, v in (properties or {}).items():
5661        child.set(k, v)
5662    instance.set(arg, child)
5663
5664    return instance
5665
5666
5667def _apply_list_builder(
5668    *expressions,
5669    instance,
5670    arg,
5671    append=True,
5672    copy=True,
5673    prefix=None,
5674    into=None,
5675    dialect=None,
5676    **opts,
5677):
5678    inst = maybe_copy(instance, copy)
5679
5680    expressions = [
5681        maybe_parse(
5682            sql_or_expression=expression,
5683            into=into,
5684            prefix=prefix,
5685            dialect=dialect,
5686            **opts,
5687        )
5688        for expression in expressions
5689        if expression is not None
5690    ]
5691
5692    existing_expressions = inst.args.get(arg)
5693    if append and existing_expressions:
5694        expressions = existing_expressions + expressions
5695
5696    inst.set(arg, expressions)
5697    return inst
5698
5699
5700def _apply_conjunction_builder(
5701    *expressions,
5702    instance,
5703    arg,
5704    into=None,
5705    append=True,
5706    copy=True,
5707    dialect=None,
5708    **opts,
5709):
5710    expressions = [exp for exp in expressions if exp is not None and exp != ""]
5711    if not expressions:
5712        return instance
5713
5714    inst = maybe_copy(instance, copy)
5715
5716    existing = inst.args.get(arg)
5717    if append and existing is not None:
5718        expressions = [existing.this if into else existing] + list(expressions)
5719
5720    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
5721
5722    inst.set(arg, into(this=node) if into else node)
5723    return inst
5724
5725
5726def _apply_cte_builder(
5727    instance: E,
5728    alias: ExpOrStr,
5729    as_: ExpOrStr,
5730    recursive: t.Optional[bool] = None,
5731    append: bool = True,
5732    dialect: DialectType = None,
5733    copy: bool = True,
5734    **opts,
5735) -> E:
5736    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
5737    as_expression = maybe_parse(as_, dialect=dialect, **opts)
5738    cte = CTE(this=as_expression, alias=alias_expression)
5739    return _apply_child_list_builder(
5740        cte,
5741        instance=instance,
5742        arg="with",
5743        append=append,
5744        copy=copy,
5745        into=With,
5746        properties={"recursive": recursive or False},
5747    )
5748
5749
5750def _combine(
5751    expressions: t.Sequence[t.Optional[ExpOrStr]],
5752    operator: t.Type[Connector],
5753    dialect: DialectType = None,
5754    copy: bool = True,
5755    **opts,
5756) -> Expression:
5757    conditions = [
5758        condition(expression, dialect=dialect, copy=copy, **opts)
5759        for expression in expressions
5760        if expression is not None
5761    ]
5762
5763    this, *rest = conditions
5764    if rest:
5765        this = _wrap(this, Connector)
5766    for expression in rest:
5767        this = operator(this=this, expression=_wrap(expression, Connector))
5768
5769    return this
5770
5771
5772def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
5773    return Paren(this=expression) if isinstance(expression, kind) else expression
5774
5775
5776def union(
5777    left: ExpOrStr,
5778    right: ExpOrStr,
5779    distinct: bool = True,
5780    dialect: DialectType = None,
5781    copy: bool = True,
5782    **opts,
5783) -> Union:
5784    """
5785    Initializes a syntax tree from one UNION expression.
5786
5787    Example:
5788        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5789        'SELECT * FROM foo UNION SELECT * FROM bla'
5790
5791    Args:
5792        left: the SQL code string corresponding to the left-hand side.
5793            If an `Expression` instance is passed, it will be used as-is.
5794        right: the SQL code string corresponding to the right-hand side.
5795            If an `Expression` instance is passed, it will be used as-is.
5796        distinct: set the DISTINCT flag if and only if this is true.
5797        dialect: the dialect used to parse the input expression.
5798        copy: whether or not to copy the expression.
5799        opts: other options to use to parse the input expressions.
5800
5801    Returns:
5802        The new Union instance.
5803    """
5804    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5805    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5806
5807    return Union(this=left, expression=right, distinct=distinct)
5808
5809
5810def intersect(
5811    left: ExpOrStr,
5812    right: ExpOrStr,
5813    distinct: bool = True,
5814    dialect: DialectType = None,
5815    copy: bool = True,
5816    **opts,
5817) -> Intersect:
5818    """
5819    Initializes a syntax tree from one INTERSECT expression.
5820
5821    Example:
5822        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5823        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5824
5825    Args:
5826        left: the SQL code string corresponding to the left-hand side.
5827            If an `Expression` instance is passed, it will be used as-is.
5828        right: the SQL code string corresponding to the right-hand side.
5829            If an `Expression` instance is passed, it will be used as-is.
5830        distinct: set the DISTINCT flag if and only if this is true.
5831        dialect: the dialect used to parse the input expression.
5832        copy: whether or not to copy the expression.
5833        opts: other options to use to parse the input expressions.
5834
5835    Returns:
5836        The new Intersect instance.
5837    """
5838    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5839    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5840
5841    return Intersect(this=left, expression=right, distinct=distinct)
5842
5843
5844def except_(
5845    left: ExpOrStr,
5846    right: ExpOrStr,
5847    distinct: bool = True,
5848    dialect: DialectType = None,
5849    copy: bool = True,
5850    **opts,
5851) -> Except:
5852    """
5853    Initializes a syntax tree from one EXCEPT expression.
5854
5855    Example:
5856        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5857        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5858
5859    Args:
5860        left: the SQL code string corresponding to the left-hand side.
5861            If an `Expression` instance is passed, it will be used as-is.
5862        right: the SQL code string corresponding to the right-hand side.
5863            If an `Expression` instance is passed, it will be used as-is.
5864        distinct: set the DISTINCT flag if and only if this is true.
5865        dialect: the dialect used to parse the input expression.
5866        copy: whether or not to copy the expression.
5867        opts: other options to use to parse the input expressions.
5868
5869    Returns:
5870        The new Except instance.
5871    """
5872    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5873    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5874
5875    return Except(this=left, expression=right, distinct=distinct)
5876
5877
5878def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5879    """
5880    Initializes a syntax tree from one or multiple SELECT expressions.
5881
5882    Example:
5883        >>> select("col1", "col2").from_("tbl").sql()
5884        'SELECT col1, col2 FROM tbl'
5885
5886    Args:
5887        *expressions: the SQL code string to parse as the expressions of a
5888            SELECT statement. If an Expression instance is passed, this is used as-is.
5889        dialect: the dialect used to parse the input expressions (in the case that an
5890            input expression is a SQL string).
5891        **opts: other options to use to parse the input expressions (again, in the case
5892            that an input expression is a SQL string).
5893
5894    Returns:
5895        Select: the syntax tree for the SELECT statement.
5896    """
5897    return Select().select(*expressions, dialect=dialect, **opts)
5898
5899
5900def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5901    """
5902    Initializes a syntax tree from a FROM expression.
5903
5904    Example:
5905        >>> from_("tbl").select("col1", "col2").sql()
5906        'SELECT col1, col2 FROM tbl'
5907
5908    Args:
5909        *expression: the SQL code string to parse as the FROM expressions of a
5910            SELECT statement. If an Expression instance is passed, this is used as-is.
5911        dialect: the dialect used to parse the input expression (in the case that the
5912            input expression is a SQL string).
5913        **opts: other options to use to parse the input expressions (again, in the case
5914            that the input expression is a SQL string).
5915
5916    Returns:
5917        Select: the syntax tree for the SELECT statement.
5918    """
5919    return Select().from_(expression, dialect=dialect, **opts)
5920
5921
5922def update(
5923    table: str | Table,
5924    properties: dict,
5925    where: t.Optional[ExpOrStr] = None,
5926    from_: t.Optional[ExpOrStr] = None,
5927    dialect: DialectType = None,
5928    **opts,
5929) -> Update:
5930    """
5931    Creates an update statement.
5932
5933    Example:
5934        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5935        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5936
5937    Args:
5938        *properties: dictionary of properties to set which are
5939            auto converted to sql objects eg None -> NULL
5940        where: sql conditional parsed into a WHERE statement
5941        from_: sql statement parsed into a FROM statement
5942        dialect: the dialect used to parse the input expressions.
5943        **opts: other options to use to parse the input expressions.
5944
5945    Returns:
5946        Update: the syntax tree for the UPDATE statement.
5947    """
5948    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5949    update_expr.set(
5950        "expressions",
5951        [
5952            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5953            for k, v in properties.items()
5954        ],
5955    )
5956    if from_:
5957        update_expr.set(
5958            "from",
5959            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5960        )
5961    if isinstance(where, Condition):
5962        where = Where(this=where)
5963    if where:
5964        update_expr.set(
5965            "where",
5966            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5967        )
5968    return update_expr
5969
5970
5971def delete(
5972    table: ExpOrStr,
5973    where: t.Optional[ExpOrStr] = None,
5974    returning: t.Optional[ExpOrStr] = None,
5975    dialect: DialectType = None,
5976    **opts,
5977) -> Delete:
5978    """
5979    Builds a delete statement.
5980
5981    Example:
5982        >>> delete("my_table", where="id > 1").sql()
5983        'DELETE FROM my_table WHERE id > 1'
5984
5985    Args:
5986        where: sql conditional parsed into a WHERE statement
5987        returning: sql conditional parsed into a RETURNING statement
5988        dialect: the dialect used to parse the input expressions.
5989        **opts: other options to use to parse the input expressions.
5990
5991    Returns:
5992        Delete: the syntax tree for the DELETE statement.
5993    """
5994    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5995    if where:
5996        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5997    if returning:
5998        delete_expr = t.cast(
5999            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6000        )
6001    return delete_expr
6002
6003
6004def insert(
6005    expression: ExpOrStr,
6006    into: ExpOrStr,
6007    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6008    overwrite: t.Optional[bool] = None,
6009    returning: t.Optional[ExpOrStr] = None,
6010    dialect: DialectType = None,
6011    copy: bool = True,
6012    **opts,
6013) -> Insert:
6014    """
6015    Builds an INSERT statement.
6016
6017    Example:
6018        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6019        'INSERT INTO tbl VALUES (1, 2, 3)'
6020
6021    Args:
6022        expression: the sql string or expression of the INSERT statement
6023        into: the tbl to insert data to.
6024        columns: optionally the table's column names.
6025        overwrite: whether to INSERT OVERWRITE or not.
6026        returning: sql conditional parsed into a RETURNING statement
6027        dialect: the dialect used to parse the input expressions.
6028        copy: whether or not to copy the expression.
6029        **opts: other options to use to parse the input expressions.
6030
6031    Returns:
6032        Insert: the syntax tree for the INSERT statement.
6033    """
6034    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6035    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6036
6037    if columns:
6038        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6039
6040    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6041
6042    if returning:
6043        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6044
6045    return insert
6046
6047
6048def condition(
6049    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6050) -> Condition:
6051    """
6052    Initialize a logical condition expression.
6053
6054    Example:
6055        >>> condition("x=1").sql()
6056        'x = 1'
6057
6058        This is helpful for composing larger logical syntax trees:
6059        >>> where = condition("x=1")
6060        >>> where = where.and_("y=1")
6061        >>> Select().from_("tbl").select("*").where(where).sql()
6062        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6063
6064    Args:
6065        *expression: the SQL code string to parse.
6066            If an Expression instance is passed, this is used as-is.
6067        dialect: the dialect used to parse the input expression (in the case that the
6068            input expression is a SQL string).
6069        copy: Whether or not to copy `expression` (only applies to expressions).
6070        **opts: other options to use to parse the input expressions (again, in the case
6071            that the input expression is a SQL string).
6072
6073    Returns:
6074        The new Condition instance
6075    """
6076    return maybe_parse(
6077        expression,
6078        into=Condition,
6079        dialect=dialect,
6080        copy=copy,
6081        **opts,
6082    )
6083
6084
6085def and_(
6086    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6087) -> Condition:
6088    """
6089    Combine multiple conditions with an AND logical operator.
6090
6091    Example:
6092        >>> and_("x=1", and_("y=1", "z=1")).sql()
6093        'x = 1 AND (y = 1 AND z = 1)'
6094
6095    Args:
6096        *expressions: the SQL code strings to parse.
6097            If an Expression instance is passed, this is used as-is.
6098        dialect: the dialect used to parse the input expression.
6099        copy: whether or not to copy `expressions` (only applies to Expressions).
6100        **opts: other options to use to parse the input expressions.
6101
6102    Returns:
6103        And: the new condition
6104    """
6105    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
6106
6107
6108def or_(
6109    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6110) -> Condition:
6111    """
6112    Combine multiple conditions with an OR logical operator.
6113
6114    Example:
6115        >>> or_("x=1", or_("y=1", "z=1")).sql()
6116        'x = 1 OR (y = 1 OR z = 1)'
6117
6118    Args:
6119        *expressions: the SQL code strings to parse.
6120            If an Expression instance is passed, this is used as-is.
6121        dialect: the dialect used to parse the input expression.
6122        copy: whether or not to copy `expressions` (only applies to Expressions).
6123        **opts: other options to use to parse the input expressions.
6124
6125    Returns:
6126        Or: the new condition
6127    """
6128    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
6129
6130
6131def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6132    """
6133    Wrap a condition with a NOT operator.
6134
6135    Example:
6136        >>> not_("this_suit='black'").sql()
6137        "NOT this_suit = 'black'"
6138
6139    Args:
6140        expression: the SQL code string to parse.
6141            If an Expression instance is passed, this is used as-is.
6142        dialect: the dialect used to parse the input expression.
6143        copy: whether to copy the expression or not.
6144        **opts: other options to use to parse the input expressions.
6145
6146    Returns:
6147        The new condition.
6148    """
6149    this = condition(
6150        expression,
6151        dialect=dialect,
6152        copy=copy,
6153        **opts,
6154    )
6155    return Not(this=_wrap(this, Connector))
6156
6157
6158def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6159    """
6160    Wrap an expression in parentheses.
6161
6162    Example:
6163        >>> paren("5 + 3").sql()
6164        '(5 + 3)'
6165
6166    Args:
6167        expression: the SQL code string to parse.
6168            If an Expression instance is passed, this is used as-is.
6169        copy: whether to copy the expression or not.
6170
6171    Returns:
6172        The wrapped expression.
6173    """
6174    return Paren(this=maybe_parse(expression, copy=copy))
6175
6176
6177SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$")
6178
6179
6180@t.overload
6181def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
6182
6183
6184@t.overload
6185def to_identifier(
6186    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
6187) -> Identifier: ...
6188
6189
6190def to_identifier(name, quoted=None, copy=True):
6191    """Builds an identifier.
6192
6193    Args:
6194        name: The name to turn into an identifier.
6195        quoted: Whether or not force quote the identifier.
6196        copy: Whether or not to copy name if it's an Identifier.
6197
6198    Returns:
6199        The identifier ast node.
6200    """
6201
6202    if name is None:
6203        return None
6204
6205    if isinstance(name, Identifier):
6206        identifier = maybe_copy(name, copy)
6207    elif isinstance(name, str):
6208        identifier = Identifier(
6209            this=name,
6210            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6211        )
6212    else:
6213        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6214    return identifier
6215
6216
6217def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6218    """
6219    Parses a given string into an identifier.
6220
6221    Args:
6222        name: The name to parse into an identifier.
6223        dialect: The dialect to parse against.
6224
6225    Returns:
6226        The identifier ast node.
6227    """
6228    try:
6229        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6230    except ParseError:
6231        expression = to_identifier(name)
6232
6233    return expression
6234
6235
6236INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6237
6238
6239def to_interval(interval: str | Literal) -> Interval:
6240    """Builds an interval expression from a string like '1 day' or '5 months'."""
6241    if isinstance(interval, Literal):
6242        if not interval.is_string:
6243            raise ValueError("Invalid interval string.")
6244
6245        interval = interval.this
6246
6247    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6248
6249    if not interval_parts:
6250        raise ValueError("Invalid interval string.")
6251
6252    return Interval(
6253        this=Literal.string(interval_parts.group(1)),
6254        unit=Var(this=interval_parts.group(2).upper()),
6255    )
6256
6257
6258@t.overload
6259def to_table(sql_path: str | Table, **kwargs) -> Table: ...
6260
6261
6262@t.overload
6263def to_table(sql_path: None, **kwargs) -> None: ...
6264
6265
6266def to_table(
6267    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6268) -> t.Optional[Table]:
6269    """
6270    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6271    If a table is passed in then that table is returned.
6272
6273    Args:
6274        sql_path: a `[catalog].[schema].[table]` string.
6275        dialect: the source dialect according to which the table name will be parsed.
6276        copy: Whether or not to copy a table if it is passed in.
6277        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6278
6279    Returns:
6280        A table expression.
6281    """
6282    if sql_path is None or isinstance(sql_path, Table):
6283        return maybe_copy(sql_path, copy=copy)
6284    if not isinstance(sql_path, str):
6285        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6286
6287    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6288    if table:
6289        for k, v in kwargs.items():
6290            table.set(k, v)
6291
6292    return table
6293
6294
6295def to_column(sql_path: str | Column, **kwargs) -> Column:
6296    """
6297    Create a column from a `[table].[column]` sql path. Schema is optional.
6298
6299    If a column is passed in then that column is returned.
6300
6301    Args:
6302        sql_path: `[table].[column]` string
6303    Returns:
6304        Table: A column expression
6305    """
6306    if sql_path is None or isinstance(sql_path, Column):
6307        return sql_path
6308    if not isinstance(sql_path, str):
6309        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6310    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
6311
6312
6313def alias_(
6314    expression: ExpOrStr,
6315    alias: str | Identifier,
6316    table: bool | t.Sequence[str | Identifier] = False,
6317    quoted: t.Optional[bool] = None,
6318    dialect: DialectType = None,
6319    copy: bool = True,
6320    **opts,
6321):
6322    """Create an Alias expression.
6323
6324    Example:
6325        >>> alias_('foo', 'bar').sql()
6326        'foo AS bar'
6327
6328        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6329        '(SELECT 1, 2) AS bar(a, b)'
6330
6331    Args:
6332        expression: the SQL code strings to parse.
6333            If an Expression instance is passed, this is used as-is.
6334        alias: the alias name to use. If the name has
6335            special characters it is quoted.
6336        table: Whether or not to create a table alias, can also be a list of columns.
6337        quoted: whether or not to quote the alias
6338        dialect: the dialect used to parse the input expression.
6339        copy: Whether or not to copy the expression.
6340        **opts: other options to use to parse the input expressions.
6341
6342    Returns:
6343        Alias: the aliased expression
6344    """
6345    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6346    alias = to_identifier(alias, quoted=quoted)
6347
6348    if table:
6349        table_alias = TableAlias(this=alias)
6350        exp.set("alias", table_alias)
6351
6352        if not isinstance(table, bool):
6353            for column in table:
6354                table_alias.append("columns", to_identifier(column, quoted=quoted))
6355
6356        return exp
6357
6358    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6359    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6360    # for the complete Window expression.
6361    #
6362    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6363
6364    if "alias" in exp.arg_types and not isinstance(exp, Window):
6365        exp.set("alias", alias)
6366        return exp
6367    return Alias(this=exp, alias=alias)
6368
6369
6370def subquery(
6371    expression: ExpOrStr,
6372    alias: t.Optional[Identifier | str] = None,
6373    dialect: DialectType = None,
6374    **opts,
6375) -> Select:
6376    """
6377    Build a subquery expression.
6378
6379    Example:
6380        >>> subquery('select x from tbl', 'bar').select('x').sql()
6381        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6382
6383    Args:
6384        expression: the SQL code strings to parse.
6385            If an Expression instance is passed, this is used as-is.
6386        alias: the alias name to use.
6387        dialect: the dialect used to parse the input expression.
6388        **opts: other options to use to parse the input expressions.
6389
6390    Returns:
6391        A new Select instance with the subquery expression included.
6392    """
6393
6394    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6395    return Select().from_(expression, dialect=dialect, **opts)
6396
6397
6398@t.overload
6399def column(
6400    col: str | Identifier,
6401    table: t.Optional[str | Identifier] = None,
6402    db: t.Optional[str | Identifier] = None,
6403    catalog: t.Optional[str | Identifier] = None,
6404    *,
6405    fields: t.Collection[t.Union[str, Identifier]],
6406    quoted: t.Optional[bool] = None,
6407    copy: bool = True,
6408) -> Dot:
6409    pass
6410
6411
6412@t.overload
6413def column(
6414    col: str | Identifier,
6415    table: t.Optional[str | Identifier] = None,
6416    db: t.Optional[str | Identifier] = None,
6417    catalog: t.Optional[str | Identifier] = None,
6418    *,
6419    fields: Lit[None] = None,
6420    quoted: t.Optional[bool] = None,
6421    copy: bool = True,
6422) -> Column:
6423    pass
6424
6425
6426def column(
6427    col,
6428    table=None,
6429    db=None,
6430    catalog=None,
6431    *,
6432    fields=None,
6433    quoted=None,
6434    copy=True,
6435):
6436    """
6437    Build a Column.
6438
6439    Args:
6440        col: Column name.
6441        table: Table name.
6442        db: Database name.
6443        catalog: Catalog name.
6444        fields: Additional fields using dots.
6445        quoted: Whether to force quotes on the column's identifiers.
6446        copy: Whether or not to copy identifiers if passed in.
6447
6448    Returns:
6449        The new Column instance.
6450    """
6451    this = Column(
6452        this=to_identifier(col, quoted=quoted, copy=copy),
6453        table=to_identifier(table, quoted=quoted, copy=copy),
6454        db=to_identifier(db, quoted=quoted, copy=copy),
6455        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6456    )
6457
6458    if fields:
6459        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6460    return this
6461
6462
6463def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6464    """Cast an expression to a data type.
6465
6466    Example:
6467        >>> cast('x + 1', 'int').sql()
6468        'CAST(x + 1 AS INT)'
6469
6470    Args:
6471        expression: The expression to cast.
6472        to: The datatype to cast to.
6473
6474    Returns:
6475        The new Cast instance.
6476    """
6477    expression = maybe_parse(expression, **opts)
6478    data_type = DataType.build(to, **opts)
6479    expression = Cast(this=expression, to=data_type)
6480    expression.type = data_type
6481    return expression
6482
6483
6484def table_(
6485    table: Identifier | str,
6486    db: t.Optional[Identifier | str] = None,
6487    catalog: t.Optional[Identifier | str] = None,
6488    quoted: t.Optional[bool] = None,
6489    alias: t.Optional[Identifier | str] = None,
6490) -> Table:
6491    """Build a Table.
6492
6493    Args:
6494        table: Table name.
6495        db: Database name.
6496        catalog: Catalog name.
6497        quote: Whether to force quotes on the table's identifiers.
6498        alias: Table's alias.
6499
6500    Returns:
6501        The new Table instance.
6502    """
6503    return Table(
6504        this=to_identifier(table, quoted=quoted) if table else None,
6505        db=to_identifier(db, quoted=quoted) if db else None,
6506        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6507        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6508    )
6509
6510
6511def values(
6512    values: t.Iterable[t.Tuple[t.Any, ...]],
6513    alias: t.Optional[str] = None,
6514    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6515) -> Values:
6516    """Build VALUES statement.
6517
6518    Example:
6519        >>> values([(1, '2')]).sql()
6520        "VALUES (1, '2')"
6521
6522    Args:
6523        values: values statements that will be converted to SQL
6524        alias: optional alias
6525        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6526         If either are provided then an alias is also required.
6527
6528    Returns:
6529        Values: the Values expression object
6530    """
6531    if columns and not alias:
6532        raise ValueError("Alias is required when providing columns")
6533
6534    return Values(
6535        expressions=[convert(tup) for tup in values],
6536        alias=(
6537            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6538            if columns
6539            else (TableAlias(this=to_identifier(alias)) if alias else None)
6540        ),
6541    )
6542
6543
6544def var(name: t.Optional[ExpOrStr]) -> Var:
6545    """Build a SQL variable.
6546
6547    Example:
6548        >>> repr(var('x'))
6549        'Var(this=x)'
6550
6551        >>> repr(var(column('x', table='y')))
6552        'Var(this=x)'
6553
6554    Args:
6555        name: The name of the var or an expression who's name will become the var.
6556
6557    Returns:
6558        The new variable node.
6559    """
6560    if not name:
6561        raise ValueError("Cannot convert empty name into var.")
6562
6563    if isinstance(name, Expression):
6564        name = name.name
6565    return Var(this=name)
6566
6567
6568def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6569    """Build ALTER TABLE... RENAME... expression
6570
6571    Args:
6572        old_name: The old name of the table
6573        new_name: The new name of the table
6574
6575    Returns:
6576        Alter table expression
6577    """
6578    old_table = to_table(old_name)
6579    new_table = to_table(new_name)
6580    return AlterTable(
6581        this=old_table,
6582        actions=[
6583            RenameTable(this=new_table),
6584        ],
6585    )
6586
6587
6588def rename_column(
6589    table_name: str | Table,
6590    old_column_name: str | Column,
6591    new_column_name: str | Column,
6592    exists: t.Optional[bool] = None,
6593) -> AlterTable:
6594    """Build ALTER TABLE... RENAME COLUMN... expression
6595
6596    Args:
6597        table_name: Name of the table
6598        old_column: The old name of the column
6599        new_column: The new name of the column
6600        exists: Whether or not to add the `IF EXISTS` clause
6601
6602    Returns:
6603        Alter table expression
6604    """
6605    table = to_table(table_name)
6606    old_column = to_column(old_column_name)
6607    new_column = to_column(new_column_name)
6608    return AlterTable(
6609        this=table,
6610        actions=[
6611            RenameColumn(this=old_column, to=new_column, exists=exists),
6612        ],
6613    )
6614
6615
6616def convert(value: t.Any, copy: bool = False) -> Expression:
6617    """Convert a python value into an expression object.
6618
6619    Raises an error if a conversion is not possible.
6620
6621    Args:
6622        value: A python object.
6623        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6624
6625    Returns:
6626        Expression: the equivalent expression object.
6627    """
6628    if isinstance(value, Expression):
6629        return maybe_copy(value, copy)
6630    if isinstance(value, str):
6631        return Literal.string(value)
6632    if isinstance(value, bool):
6633        return Boolean(this=value)
6634    if value is None or (isinstance(value, float) and math.isnan(value)):
6635        return null()
6636    if isinstance(value, numbers.Number):
6637        return Literal.number(value)
6638    if isinstance(value, datetime.datetime):
6639        datetime_literal = Literal.string(
6640            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6641        )
6642        return TimeStrToTime(this=datetime_literal)
6643    if isinstance(value, datetime.date):
6644        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6645        return DateStrToDate(this=date_literal)
6646    if isinstance(value, tuple):
6647        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6648    if isinstance(value, list):
6649        return Array(expressions=[convert(v, copy=copy) for v in value])
6650    if isinstance(value, dict):
6651        return Map(
6652            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6653            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6654        )
6655    raise ValueError(f"Cannot convert {value}")
6656
6657
6658def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6659    """
6660    Replace children of an expression with the result of a lambda fun(child) -> exp.
6661    """
6662    for k, v in expression.args.items():
6663        is_list_arg = type(v) is list
6664
6665        child_nodes = v if is_list_arg else [v]
6666        new_child_nodes = []
6667
6668        for cn in child_nodes:
6669            if isinstance(cn, Expression):
6670                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6671                    new_child_nodes.append(child_node)
6672                    child_node.parent = expression
6673                    child_node.arg_key = k
6674            else:
6675                new_child_nodes.append(cn)
6676
6677        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
6678
6679
6680def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6681    """
6682    Return all table names referenced through columns in an expression.
6683
6684    Example:
6685        >>> import sqlglot
6686        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6687        ['a', 'c']
6688
6689    Args:
6690        expression: expression to find table names.
6691        exclude: a table name to exclude
6692
6693    Returns:
6694        A list of unique names.
6695    """
6696    return {
6697        table
6698        for table in (column.table for column in expression.find_all(Column))
6699        if table and table != exclude
6700    }
6701
6702
6703def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6704    """Get the full name of a table as a string.
6705
6706    Args:
6707        table: Table expression node or string.
6708        dialect: The dialect to generate the table name for.
6709        identify: Determines when an identifier should be quoted. Possible values are:
6710            False (default): Never quote, except in cases where it's mandatory by the dialect.
6711            True: Always quote.
6712
6713    Examples:
6714        >>> from sqlglot import exp, parse_one
6715        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6716        'a.b.c'
6717
6718    Returns:
6719        The table name.
6720    """
6721
6722    table = maybe_parse(table, into=Table, dialect=dialect)
6723
6724    if not table:
6725        raise ValueError(f"Cannot parse {table}")
6726
6727    return ".".join(
6728        (
6729            part.sql(dialect=dialect, identify=True, copy=False)
6730            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6731            else part.name
6732        )
6733        for part in table.parts
6734    )
6735
6736
6737def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6738    """Returns a case normalized table name without quotes.
6739
6740    Args:
6741        table: the table to normalize
6742        dialect: the dialect to use for normalization rules
6743        copy: whether or not to copy the expression.
6744
6745    Examples:
6746        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6747        'A-B.c'
6748    """
6749    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6750
6751    return ".".join(
6752        p.name
6753        for p in normalize_identifiers(
6754            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6755        ).parts
6756    )
6757
6758
6759def replace_tables(
6760    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6761) -> E:
6762    """Replace all tables in expression according to the mapping.
6763
6764    Args:
6765        expression: expression node to be transformed and replaced.
6766        mapping: mapping of table names.
6767        dialect: the dialect of the mapping table
6768        copy: whether or not to copy the expression.
6769
6770    Examples:
6771        >>> from sqlglot import exp, parse_one
6772        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6773        'SELECT * FROM c /* a.b */'
6774
6775    Returns:
6776        The mapped expression.
6777    """
6778
6779    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6780
6781    def _replace_tables(node: Expression) -> Expression:
6782        if isinstance(node, Table):
6783            original = normalize_table_name(node, dialect=dialect)
6784            new_name = mapping.get(original)
6785
6786            if new_name:
6787                table = to_table(
6788                    new_name,
6789                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6790                )
6791                table.add_comments([original])
6792                return table
6793        return node
6794
6795    return expression.transform(_replace_tables, copy=copy)
6796
6797
6798def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6799    """Replace placeholders in an expression.
6800
6801    Args:
6802        expression: expression node to be transformed and replaced.
6803        args: positional names that will substitute unnamed placeholders in the given order.
6804        kwargs: keyword arguments that will substitute named placeholders.
6805
6806    Examples:
6807        >>> from sqlglot import exp, parse_one
6808        >>> replace_placeholders(
6809        ...     parse_one("select * from :tbl where ? = ?"),
6810        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6811        ... ).sql()
6812        "SELECT * FROM foo WHERE str_col = 'b'"
6813
6814    Returns:
6815        The mapped expression.
6816    """
6817
6818    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6819        if isinstance(node, Placeholder):
6820            if node.name:
6821                new_name = kwargs.get(node.name)
6822                if new_name:
6823                    return convert(new_name)
6824            else:
6825                try:
6826                    return convert(next(args))
6827                except StopIteration:
6828                    pass
6829        return node
6830
6831    return expression.transform(_replace_placeholders, iter(args), **kwargs)
6832
6833
6834def expand(
6835    expression: Expression,
6836    sources: t.Dict[str, Subqueryable],
6837    dialect: DialectType = None,
6838    copy: bool = True,
6839) -> Expression:
6840    """Transforms an expression by expanding all referenced sources into subqueries.
6841
6842    Examples:
6843        >>> from sqlglot import parse_one
6844        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6845        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6846
6847        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6848        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6849
6850    Args:
6851        expression: The expression to expand.
6852        sources: A dictionary of name to Subqueryables.
6853        dialect: The dialect of the sources dict.
6854        copy: Whether or not to copy the expression during transformation. Defaults to True.
6855
6856    Returns:
6857        The transformed expression.
6858    """
6859    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6860
6861    def _expand(node: Expression):
6862        if isinstance(node, Table):
6863            name = normalize_table_name(node, dialect=dialect)
6864            source = sources.get(name)
6865            if source:
6866                subquery = source.subquery(node.alias or name)
6867                subquery.comments = [f"source: {name}"]
6868                return subquery.transform(_expand, copy=False)
6869        return node
6870
6871    return expression.transform(_expand, copy=copy)
6872
6873
6874def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6875    """
6876    Returns a Func expression.
6877
6878    Examples:
6879        >>> func("abs", 5).sql()
6880        'ABS(5)'
6881
6882        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6883        'CAST(5 AS DOUBLE)'
6884
6885    Args:
6886        name: the name of the function to build.
6887        args: the args used to instantiate the function of interest.
6888        copy: whether or not to copy the argument expressions.
6889        dialect: the source dialect.
6890        kwargs: the kwargs used to instantiate the function of interest.
6891
6892    Note:
6893        The arguments `args` and `kwargs` are mutually exclusive.
6894
6895    Returns:
6896        An instance of the function of interest, or an anonymous function, if `name` doesn't
6897        correspond to an existing `sqlglot.expressions.Func` class.
6898    """
6899    if args and kwargs:
6900        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6901
6902    from sqlglot.dialects.dialect import Dialect
6903
6904    dialect = Dialect.get_or_raise(dialect)
6905
6906    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6907    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6908
6909    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6910    if constructor:
6911        if converted:
6912            if "dialect" in constructor.__code__.co_varnames:
6913                function = constructor(converted, dialect=dialect)
6914            else:
6915                function = constructor(converted)
6916        elif constructor.__name__ == "from_arg_list":
6917            function = constructor.__self__(**kwargs)  # type: ignore
6918        else:
6919            constructor = FUNCTION_BY_NAME.get(name.upper())
6920            if constructor:
6921                function = constructor(**kwargs)
6922            else:
6923                raise ValueError(
6924                    f"Unable to convert '{name}' into a Func. Either manually construct "
6925                    "the Func expression of interest or parse the function call."
6926                )
6927    else:
6928        kwargs = kwargs or {"expressions": converted}
6929        function = Anonymous(this=name, **kwargs)
6930
6931    for error_message in function.error_messages(converted):
6932        raise ValueError(error_message)
6933
6934    return function
6935
6936
6937def case(
6938    expression: t.Optional[ExpOrStr] = None,
6939    **opts,
6940) -> Case:
6941    """
6942    Initialize a CASE statement.
6943
6944    Example:
6945        case().when("a = 1", "foo").else_("bar")
6946
6947    Args:
6948        expression: Optionally, the input expression (not all dialects support this)
6949        **opts: Extra keyword arguments for parsing `expression`
6950    """
6951    if expression is not None:
6952        this = maybe_parse(expression, **opts)
6953    else:
6954        this = None
6955    return Case(this=this, ifs=[])
6956
6957
6958def cast_unless(
6959    expression: ExpOrStr,
6960    to: DATA_TYPE,
6961    *types: DATA_TYPE,
6962    **opts: t.Any,
6963) -> Expression | Cast:
6964    """
6965    Cast an expression to a data type unless it is a specified type.
6966
6967    Args:
6968        expression: The expression to cast.
6969        to: The data type to cast to.
6970        **types: The types to exclude from casting.
6971        **opts: Extra keyword arguments for parsing `expression`
6972    """
6973    expr = maybe_parse(expression, **opts)
6974    if expr.is_type(*types):
6975        return expr
6976    return cast(expr, to, **opts)
6977
6978
6979def true() -> Boolean:
6980    """
6981    Returns a true Boolean expression.
6982    """
6983    return Boolean(this=True)
6984
6985
6986def false() -> Boolean:
6987    """
6988    Returns a false Boolean expression.
6989    """
6990    return Boolean(this=False)
6991
6992
6993def null() -> Null:
6994    """
6995    Returns a Null expression.
6996    """
6997    return Null()
SQLGLOT_META = 'sqlglot.meta'
TABLE_PARTS = ('this', 'db', 'catalog')
class Expression:
 61class Expression(metaclass=_Expression):
 62    """
 63    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
 64    context, such as its child expressions, their names (arg keys), and whether a given child expression
 65    is optional or not.
 66
 67    Attributes:
 68        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
 69            and representing expressions as strings.
 70        arg_types: determines what arguments (child nodes) are supported by an expression. It
 71            maps arg keys to booleans that indicate whether the corresponding args are optional.
 72        parent: a reference to the parent expression (or None, in case of root expressions).
 73        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
 74            uses to refer to it.
 75        comments: a list of comments that are associated with a given expression. This is used in
 76            order to preserve comments when transpiling SQL code.
 77        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
 78            optimizer, in order to enable some transformations that require type information.
 79        meta: a dictionary that can be used to store useful metadata for a given expression.
 80
 81    Example:
 82        >>> class Foo(Expression):
 83        ...     arg_types = {"this": True, "expression": False}
 84
 85        The above definition informs us that Foo is an Expression that requires an argument called
 86        "this" and may also optionally receive an argument called "expression".
 87
 88    Args:
 89        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
 90    """
 91
 92    key = "expression"
 93    arg_types = {"this": True}
 94    __slots__ = ("args", "parent", "arg_key", "comments", "_type", "_meta", "_hash")
 95
 96    def __init__(self, **args: t.Any):
 97        self.args: t.Dict[str, t.Any] = args
 98        self.parent: t.Optional[Expression] = None
 99        self.arg_key: t.Optional[str] = None
100        self.comments: t.Optional[t.List[str]] = None
101        self._type: t.Optional[DataType] = None
102        self._meta: t.Optional[t.Dict[str, t.Any]] = None
103        self._hash: t.Optional[int] = None
104
105        for arg_key, value in self.args.items():
106            self._set_parent(arg_key, value)
107
108    def __eq__(self, other) -> bool:
109        return type(self) is type(other) and hash(self) == hash(other)
110
111    @property
112    def hashable_args(self) -> t.Any:
113        return frozenset(
114            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
115            for k, v in self.args.items()
116            if not (v is None or v is False or (type(v) is list and not v))
117        )
118
119    def __hash__(self) -> int:
120        if self._hash is not None:
121            return self._hash
122
123        return hash((self.__class__, self.hashable_args))
124
125    @property
126    def this(self) -> t.Any:
127        """
128        Retrieves the argument with key "this".
129        """
130        return self.args.get("this")
131
132    @property
133    def expression(self) -> t.Any:
134        """
135        Retrieves the argument with key "expression".
136        """
137        return self.args.get("expression")
138
139    @property
140    def expressions(self) -> t.List[t.Any]:
141        """
142        Retrieves the argument with key "expressions".
143        """
144        return self.args.get("expressions") or []
145
146    def text(self, key) -> str:
147        """
148        Returns a textual representation of the argument corresponding to "key". This can only be used
149        for args that are strings or leaf Expression instances, such as identifiers and literals.
150        """
151        field = self.args.get(key)
152        if isinstance(field, str):
153            return field
154        if isinstance(field, (Identifier, Literal, Var)):
155            return field.this
156        if isinstance(field, (Star, Null)):
157            return field.name
158        return ""
159
160    @property
161    def is_string(self) -> bool:
162        """
163        Checks whether a Literal expression is a string.
164        """
165        return isinstance(self, Literal) and self.args["is_string"]
166
167    @property
168    def is_number(self) -> bool:
169        """
170        Checks whether a Literal expression is a number.
171        """
172        return isinstance(self, Literal) and not self.args["is_string"]
173
174    @property
175    def is_int(self) -> bool:
176        """
177        Checks whether a Literal expression is an integer.
178        """
179        if self.is_number:
180            try:
181                int(self.name)
182                return True
183            except ValueError:
184                pass
185        return False
186
187    @property
188    def is_star(self) -> bool:
189        """Checks whether an expression is a star."""
190        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
191
192    @property
193    def alias(self) -> str:
194        """
195        Returns the alias of the expression, or an empty string if it's not aliased.
196        """
197        if isinstance(self.args.get("alias"), TableAlias):
198            return self.args["alias"].name
199        return self.text("alias")
200
201    @property
202    def alias_column_names(self) -> t.List[str]:
203        table_alias = self.args.get("alias")
204        if not table_alias:
205            return []
206        return [c.name for c in table_alias.args.get("columns") or []]
207
208    @property
209    def name(self) -> str:
210        return self.text("this")
211
212    @property
213    def alias_or_name(self) -> str:
214        return self.alias or self.name
215
216    @property
217    def output_name(self) -> str:
218        """
219        Name of the output column if this expression is a selection.
220
221        If the Expression has no output name, an empty string is returned.
222
223        Example:
224            >>> from sqlglot import parse_one
225            >>> parse_one("SELECT a").expressions[0].output_name
226            'a'
227            >>> parse_one("SELECT b AS c").expressions[0].output_name
228            'c'
229            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
230            ''
231        """
232        return ""
233
234    @property
235    def type(self) -> t.Optional[DataType]:
236        return self._type
237
238    @type.setter
239    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
240        if dtype and not isinstance(dtype, DataType):
241            dtype = DataType.build(dtype)
242        self._type = dtype  # type: ignore
243
244    def is_type(self, *dtypes) -> bool:
245        return self.type is not None and self.type.is_type(*dtypes)
246
247    def is_leaf(self) -> bool:
248        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
249
250    @property
251    def meta(self) -> t.Dict[str, t.Any]:
252        if self._meta is None:
253            self._meta = {}
254        return self._meta
255
256    def __deepcopy__(self, memo):
257        copy = self.__class__(**deepcopy(self.args))
258        if self.comments is not None:
259            copy.comments = deepcopy(self.comments)
260
261        if self._type is not None:
262            copy._type = self._type.copy()
263
264        if self._meta is not None:
265            copy._meta = deepcopy(self._meta)
266
267        return copy
268
269    def copy(self):
270        """
271        Returns a deep copy of the expression.
272        """
273        new = deepcopy(self)
274        new.parent = self.parent
275        return new
276
277    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
278        if self.comments is None:
279            self.comments = []
280        if comments:
281            for comment in comments:
282                _, *meta = comment.split(SQLGLOT_META)
283                if meta:
284                    for kv in "".join(meta).split(","):
285                        k, *v = kv.split("=")
286                        value = v[0].strip() if v else True
287                        self.meta[k.strip()] = value
288                self.comments.append(comment)
289
290    def append(self, arg_key: str, value: t.Any) -> None:
291        """
292        Appends value to arg_key if it's a list or sets it as a new list.
293
294        Args:
295            arg_key (str): name of the list expression arg
296            value (Any): value to append to the list
297        """
298        if not isinstance(self.args.get(arg_key), list):
299            self.args[arg_key] = []
300        self.args[arg_key].append(value)
301        self._set_parent(arg_key, value)
302
303    def set(self, arg_key: str, value: t.Any) -> None:
304        """
305        Sets arg_key to value.
306
307        Args:
308            arg_key: name of the expression arg.
309            value: value to set the arg to.
310        """
311        if value is None:
312            self.args.pop(arg_key, None)
313            return
314
315        self.args[arg_key] = value
316        self._set_parent(arg_key, value)
317
318    def _set_parent(self, arg_key: str, value: t.Any) -> None:
319        if hasattr(value, "parent"):
320            value.parent = self
321            value.arg_key = arg_key
322        elif type(value) is list:
323            for v in value:
324                if hasattr(v, "parent"):
325                    v.parent = self
326                    v.arg_key = arg_key
327
328    @property
329    def depth(self) -> int:
330        """
331        Returns the depth of this tree.
332        """
333        if self.parent:
334            return self.parent.depth + 1
335        return 0
336
337    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
338        """Yields the key and expression for all arguments, exploding list args."""
339        for k, vs in self.args.items():
340            if type(vs) is list:
341                for v in vs:
342                    if hasattr(v, "parent"):
343                        yield k, v
344            else:
345                if hasattr(vs, "parent"):
346                    yield k, vs
347
348    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
349        """
350        Returns the first node in this tree which matches at least one of
351        the specified types.
352
353        Args:
354            expression_types: the expression type(s) to match.
355            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
356
357        Returns:
358            The node which matches the criteria or None if no such node was found.
359        """
360        return next(self.find_all(*expression_types, bfs=bfs), None)
361
362    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
363        """
364        Returns a generator object which visits all nodes in this tree and only
365        yields those that match at least one of the specified expression types.
366
367        Args:
368            expression_types: the expression type(s) to match.
369            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
370
371        Returns:
372            The generator object.
373        """
374        for expression, *_ in self.walk(bfs=bfs):
375            if isinstance(expression, expression_types):
376                yield expression
377
378    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
379        """
380        Returns a nearest parent matching expression_types.
381
382        Args:
383            expression_types: the expression type(s) to match.
384
385        Returns:
386            The parent node.
387        """
388        ancestor = self.parent
389        while ancestor and not isinstance(ancestor, expression_types):
390            ancestor = ancestor.parent
391        return ancestor  # type: ignore
392
393    @property
394    def parent_select(self) -> t.Optional[Select]:
395        """
396        Returns the parent select statement.
397        """
398        return self.find_ancestor(Select)
399
400    @property
401    def same_parent(self) -> bool:
402        """Returns if the parent is the same class as itself."""
403        return type(self.parent) is self.__class__
404
405    def root(self) -> Expression:
406        """
407        Returns the root expression of this tree.
408        """
409        expression = self
410        while expression.parent:
411            expression = expression.parent
412        return expression
413
414    def walk(self, bfs=True, prune=None):
415        """
416        Returns a generator object which visits all nodes in this tree.
417
418        Args:
419            bfs (bool): if set to True the BFS traversal order will be applied,
420                otherwise the DFS traversal will be used instead.
421            prune ((node, parent, arg_key) -> bool): callable that returns True if
422                the generator should stop traversing this branch of the tree.
423
424        Returns:
425            the generator object.
426        """
427        if bfs:
428            yield from self.bfs(prune=prune)
429        else:
430            yield from self.dfs(prune=prune)
431
432    def dfs(self, parent=None, key=None, prune=None):
433        """
434        Returns a generator object which visits all nodes in this tree in
435        the DFS (Depth-first) order.
436
437        Returns:
438            The generator object.
439        """
440        parent = parent or self.parent
441        yield self, parent, key
442        if prune and prune(self, parent, key):
443            return
444
445        for k, v in self.iter_expressions():
446            yield from v.dfs(self, k, prune)
447
448    def bfs(self, prune=None):
449        """
450        Returns a generator object which visits all nodes in this tree in
451        the BFS (Breadth-first) order.
452
453        Returns:
454            The generator object.
455        """
456        queue = deque([(self, self.parent, None)])
457
458        while queue:
459            item, parent, key = queue.popleft()
460
461            yield item, parent, key
462            if prune and prune(item, parent, key):
463                continue
464
465            for k, v in item.iter_expressions():
466                queue.append((v, item, k))
467
468    def unnest(self):
469        """
470        Returns the first non parenthesis child or self.
471        """
472        expression = self
473        while type(expression) is Paren:
474            expression = expression.this
475        return expression
476
477    def unalias(self):
478        """
479        Returns the inner expression if this is an Alias.
480        """
481        if isinstance(self, Alias):
482            return self.this
483        return self
484
485    def unnest_operands(self):
486        """
487        Returns unnested operands as a tuple.
488        """
489        return tuple(arg.unnest() for _, arg in self.iter_expressions())
490
491    def flatten(self, unnest=True):
492        """
493        Returns a generator which yields child nodes whose parents are the same class.
494
495        A AND B AND C -> [A, B, C]
496        """
497        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
498            if not type(node) is self.__class__:
499                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
500
501    def __str__(self) -> str:
502        return self.sql()
503
504    def __repr__(self) -> str:
505        return _to_s(self)
506
507    def to_s(self) -> str:
508        """
509        Same as __repr__, but includes additional information which can be useful
510        for debugging, like empty or missing args and the AST nodes' object IDs.
511        """
512        return _to_s(self, verbose=True)
513
514    def sql(self, dialect: DialectType = None, **opts) -> str:
515        """
516        Returns SQL string representation of this tree.
517
518        Args:
519            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
520            opts: other `sqlglot.generator.Generator` options.
521
522        Returns:
523            The SQL string.
524        """
525        from sqlglot.dialects import Dialect
526
527        return Dialect.get_or_raise(dialect).generate(self, **opts)
528
529    def transform(self, fun, *args, copy=True, **kwargs):
530        """
531        Recursively visits all tree nodes (excluding already transformed ones)
532        and applies the given transformation function to each node.
533
534        Args:
535            fun (function): a function which takes a node as an argument and returns a
536                new transformed node or the same node without modifications. If the function
537                returns None, then the corresponding node will be removed from the syntax tree.
538            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
539                modified in place.
540
541        Returns:
542            The transformed tree.
543        """
544        node = self.copy() if copy else self
545        new_node = fun(node, *args, **kwargs)
546
547        if new_node is None or not isinstance(new_node, Expression):
548            return new_node
549        if new_node is not node:
550            new_node.parent = node.parent
551            return new_node
552
553        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
554        return new_node
555
556    @t.overload
557    def replace(self, expression: E) -> E: ...
558
559    @t.overload
560    def replace(self, expression: None) -> None: ...
561
562    def replace(self, expression):
563        """
564        Swap out this expression with a new expression.
565
566        For example::
567
568            >>> tree = Select().select("x").from_("tbl")
569            >>> tree.find(Column).replace(column("y"))
570            Column(
571              this=Identifier(this=y, quoted=False))
572            >>> tree.sql()
573            'SELECT y FROM tbl'
574
575        Args:
576            expression: new node
577
578        Returns:
579            The new expression or expressions.
580        """
581        if not self.parent:
582            return expression
583
584        parent = self.parent
585        self.parent = None
586
587        replace_children(parent, lambda child: expression if child is self else child)
588        return expression
589
590    def pop(self: E) -> E:
591        """
592        Remove this expression from its AST.
593
594        Returns:
595            The popped expression.
596        """
597        self.replace(None)
598        return self
599
600    def assert_is(self, type_: t.Type[E]) -> E:
601        """
602        Assert that this `Expression` is an instance of `type_`.
603
604        If it is NOT an instance of `type_`, this raises an assertion error.
605        Otherwise, this returns this expression.
606
607        Examples:
608            This is useful for type security in chained expressions:
609
610            >>> import sqlglot
611            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
612            'SELECT x, z FROM y'
613        """
614        assert isinstance(self, type_)
615        return self
616
617    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
618        """
619        Checks if this expression is valid (e.g. all mandatory args are set).
620
621        Args:
622            args: a sequence of values that were used to instantiate a Func expression. This is used
623                to check that the provided arguments don't exceed the function argument limit.
624
625        Returns:
626            A list of error messages for all possible errors that were found.
627        """
628        errors: t.List[str] = []
629
630        for k in self.args:
631            if k not in self.arg_types:
632                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
633        for k, mandatory in self.arg_types.items():
634            v = self.args.get(k)
635            if mandatory and (v is None or (isinstance(v, list) and not v)):
636                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
637
638        if (
639            args
640            and isinstance(self, Func)
641            and len(args) > len(self.arg_types)
642            and not self.is_var_len_args
643        ):
644            errors.append(
645                f"The number of provided arguments ({len(args)}) is greater than "
646                f"the maximum number of supported arguments ({len(self.arg_types)})"
647            )
648
649        return errors
650
651    def dump(self):
652        """
653        Dump this Expression to a JSON-serializable dict.
654        """
655        from sqlglot.serde import dump
656
657        return dump(self)
658
659    @classmethod
660    def load(cls, obj):
661        """
662        Load a dict (as returned by `Expression.dump`) into an Expression instance.
663        """
664        from sqlglot.serde import load
665
666        return load(obj)
667
668    def and_(
669        self,
670        *expressions: t.Optional[ExpOrStr],
671        dialect: DialectType = None,
672        copy: bool = True,
673        **opts,
674    ) -> Condition:
675        """
676        AND this condition with one or multiple expressions.
677
678        Example:
679            >>> condition("x=1").and_("y=1").sql()
680            'x = 1 AND y = 1'
681
682        Args:
683            *expressions: the SQL code strings to parse.
684                If an `Expression` instance is passed, it will be used as-is.
685            dialect: the dialect used to parse the input expression.
686            copy: whether or not to copy the involved expressions (only applies to Expressions).
687            opts: other options to use to parse the input expressions.
688
689        Returns:
690            The new And condition.
691        """
692        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)
693
694    def or_(
695        self,
696        *expressions: t.Optional[ExpOrStr],
697        dialect: DialectType = None,
698        copy: bool = True,
699        **opts,
700    ) -> Condition:
701        """
702        OR this condition with one or multiple expressions.
703
704        Example:
705            >>> condition("x=1").or_("y=1").sql()
706            'x = 1 OR y = 1'
707
708        Args:
709            *expressions: the SQL code strings to parse.
710                If an `Expression` instance is passed, it will be used as-is.
711            dialect: the dialect used to parse the input expression.
712            copy: whether or not to copy the involved expressions (only applies to Expressions).
713            opts: other options to use to parse the input expressions.
714
715        Returns:
716            The new Or condition.
717        """
718        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)
719
720    def not_(self, copy: bool = True):
721        """
722        Wrap this condition with NOT.
723
724        Example:
725            >>> condition("x=1").not_().sql()
726            'NOT x = 1'
727
728        Args:
729            copy: whether or not to copy this object.
730
731        Returns:
732            The new Not instance.
733        """
734        return not_(self, copy=copy)
735
736    def as_(
737        self,
738        alias: str | Identifier,
739        quoted: t.Optional[bool] = None,
740        dialect: DialectType = None,
741        copy: bool = True,
742        **opts,
743    ) -> Alias:
744        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
745
746    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
747        this = self.copy()
748        other = convert(other, copy=True)
749        if not isinstance(this, klass) and not isinstance(other, klass):
750            this = _wrap(this, Binary)
751            other = _wrap(other, Binary)
752        if reverse:
753            return klass(this=other, expression=this)
754        return klass(this=this, expression=other)
755
756    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
757        return Bracket(
758            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
759        )
760
761    def __iter__(self) -> t.Iterator:
762        if "expressions" in self.arg_types:
763            return iter(self.args.get("expressions") or [])
764        # We define this because __getitem__ converts Expression into an iterable, which is
765        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
766        # See: https://peps.python.org/pep-0234/
767        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
768
769    def isin(
770        self,
771        *expressions: t.Any,
772        query: t.Optional[ExpOrStr] = None,
773        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
774        copy: bool = True,
775        **opts,
776    ) -> In:
777        return In(
778            this=maybe_copy(self, copy),
779            expressions=[convert(e, copy=copy) for e in expressions],
780            query=maybe_parse(query, copy=copy, **opts) if query else None,
781            unnest=(
782                Unnest(
783                    expressions=[
784                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
785                        for e in ensure_list(unnest)
786                    ]
787                )
788                if unnest
789                else None
790            ),
791        )
792
793    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
794        return Between(
795            this=maybe_copy(self, copy),
796            low=convert(low, copy=copy, **opts),
797            high=convert(high, copy=copy, **opts),
798        )
799
800    def is_(self, other: ExpOrStr) -> Is:
801        return self._binop(Is, other)
802
803    def like(self, other: ExpOrStr) -> Like:
804        return self._binop(Like, other)
805
806    def ilike(self, other: ExpOrStr) -> ILike:
807        return self._binop(ILike, other)
808
809    def eq(self, other: t.Any) -> EQ:
810        return self._binop(EQ, other)
811
812    def neq(self, other: t.Any) -> NEQ:
813        return self._binop(NEQ, other)
814
815    def rlike(self, other: ExpOrStr) -> RegexpLike:
816        return self._binop(RegexpLike, other)
817
818    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
819        div = self._binop(Div, other)
820        div.args["typed"] = typed
821        div.args["safe"] = safe
822        return div
823
824    def desc(self, nulls_first: bool = False) -> Ordered:
825        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
826
827    def __lt__(self, other: t.Any) -> LT:
828        return self._binop(LT, other)
829
830    def __le__(self, other: t.Any) -> LTE:
831        return self._binop(LTE, other)
832
833    def __gt__(self, other: t.Any) -> GT:
834        return self._binop(GT, other)
835
836    def __ge__(self, other: t.Any) -> GTE:
837        return self._binop(GTE, other)
838
839    def __add__(self, other: t.Any) -> Add:
840        return self._binop(Add, other)
841
842    def __radd__(self, other: t.Any) -> Add:
843        return self._binop(Add, other, reverse=True)
844
845    def __sub__(self, other: t.Any) -> Sub:
846        return self._binop(Sub, other)
847
848    def __rsub__(self, other: t.Any) -> Sub:
849        return self._binop(Sub, other, reverse=True)
850
851    def __mul__(self, other: t.Any) -> Mul:
852        return self._binop(Mul, other)
853
854    def __rmul__(self, other: t.Any) -> Mul:
855        return self._binop(Mul, other, reverse=True)
856
857    def __truediv__(self, other: t.Any) -> Div:
858        return self._binop(Div, other)
859
860    def __rtruediv__(self, other: t.Any) -> Div:
861        return self._binop(Div, other, reverse=True)
862
863    def __floordiv__(self, other: t.Any) -> IntDiv:
864        return self._binop(IntDiv, other)
865
866    def __rfloordiv__(self, other: t.Any) -> IntDiv:
867        return self._binop(IntDiv, other, reverse=True)
868
869    def __mod__(self, other: t.Any) -> Mod:
870        return self._binop(Mod, other)
871
872    def __rmod__(self, other: t.Any) -> Mod:
873        return self._binop(Mod, other, reverse=True)
874
875    def __pow__(self, other: t.Any) -> Pow:
876        return self._binop(Pow, other)
877
878    def __rpow__(self, other: t.Any) -> Pow:
879        return self._binop(Pow, other, reverse=True)
880
881    def __and__(self, other: t.Any) -> And:
882        return self._binop(And, other)
883
884    def __rand__(self, other: t.Any) -> And:
885        return self._binop(And, other, reverse=True)
886
887    def __or__(self, other: t.Any) -> Or:
888        return self._binop(Or, other)
889
890    def __ror__(self, other: t.Any) -> Or:
891        return self._binop(Or, other, reverse=True)
892
893    def __neg__(self) -> Neg:
894        return Neg(this=_wrap(self.copy(), Binary))
895
896    def __invert__(self) -> Not:
897        return not_(self.copy())

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines what arguments (child nodes) are supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
 96    def __init__(self, **args: t.Any):
 97        self.args: t.Dict[str, t.Any] = args
 98        self.parent: t.Optional[Expression] = None
 99        self.arg_key: t.Optional[str] = None
100        self.comments: t.Optional[t.List[str]] = None
101        self._type: t.Optional[DataType] = None
102        self._meta: t.Optional[t.Dict[str, t.Any]] = None
103        self._hash: t.Optional[int] = None
104
105        for arg_key, value in self.args.items():
106            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
comments: Optional[List[str]]
hashable_args: Any
111    @property
112    def hashable_args(self) -> t.Any:
113        return frozenset(
114            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
115            for k, v in self.args.items()
116            if not (v is None or v is False or (type(v) is list and not v))
117        )
this: Any
125    @property
126    def this(self) -> t.Any:
127        """
128        Retrieves the argument with key "this".
129        """
130        return self.args.get("this")

Retrieves the argument with key "this".

expression: Any
132    @property
133    def expression(self) -> t.Any:
134        """
135        Retrieves the argument with key "expression".
136        """
137        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
139    @property
140    def expressions(self) -> t.List[t.Any]:
141        """
142        Retrieves the argument with key "expressions".
143        """
144        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
146    def text(self, key) -> str:
147        """
148        Returns a textual representation of the argument corresponding to "key". This can only be used
149        for args that are strings or leaf Expression instances, such as identifiers and literals.
150        """
151        field = self.args.get(key)
152        if isinstance(field, str):
153            return field
154        if isinstance(field, (Identifier, Literal, Var)):
155            return field.this
156        if isinstance(field, (Star, Null)):
157            return field.name
158        return ""

Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expression instances, such as identifiers and literals.

is_string: bool
160    @property
161    def is_string(self) -> bool:
162        """
163        Checks whether a Literal expression is a string.
164        """
165        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
167    @property
168    def is_number(self) -> bool:
169        """
170        Checks whether a Literal expression is a number.
171        """
172        return isinstance(self, Literal) and not self.args["is_string"]

Checks whether a Literal expression is a number.

is_int: bool
174    @property
175    def is_int(self) -> bool:
176        """
177        Checks whether a Literal expression is an integer.
178        """
179        if self.is_number:
180            try:
181                int(self.name)
182                return True
183            except ValueError:
184                pass
185        return False

Checks whether a Literal expression is an integer.

is_star: bool
187    @property
188    def is_star(self) -> bool:
189        """Checks whether an expression is a star."""
190        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
192    @property
193    def alias(self) -> str:
194        """
195        Returns the alias of the expression, or an empty string if it's not aliased.
196        """
197        if isinstance(self.args.get("alias"), TableAlias):
198            return self.args["alias"].name
199        return self.text("alias")

Returns the alias of the expression, or an empty string if it's not aliased.

alias_column_names: List[str]
201    @property
202    def alias_column_names(self) -> t.List[str]:
203        table_alias = self.args.get("alias")
204        if not table_alias:
205            return []
206        return [c.name for c in table_alias.args.get("columns") or []]
name: str
208    @property
209    def name(self) -> str:
210        return self.text("this")
alias_or_name: str
212    @property
213    def alias_or_name(self) -> str:
214        return self.alias or self.name
output_name: str
216    @property
217    def output_name(self) -> str:
218        """
219        Name of the output column if this expression is a selection.
220
221        If the Expression has no output name, an empty string is returned.
222
223        Example:
224            >>> from sqlglot import parse_one
225            >>> parse_one("SELECT a").expressions[0].output_name
226            'a'
227            >>> parse_one("SELECT b AS c").expressions[0].output_name
228            'c'
229            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
230            ''
231        """
232        return ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
234    @property
235    def type(self) -> t.Optional[DataType]:
236        return self._type
def is_type(self, *dtypes) -> bool:
244    def is_type(self, *dtypes) -> bool:
245        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
247    def is_leaf(self) -> bool:
248        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
250    @property
251    def meta(self) -> t.Dict[str, t.Any]:
252        if self._meta is None:
253            self._meta = {}
254        return self._meta
def copy(self):
269    def copy(self):
270        """
271        Returns a deep copy of the expression.
272        """
273        new = deepcopy(self)
274        new.parent = self.parent
275        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
277    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
278        if self.comments is None:
279            self.comments = []
280        if comments:
281            for comment in comments:
282                _, *meta = comment.split(SQLGLOT_META)
283                if meta:
284                    for kv in "".join(meta).split(","):
285                        k, *v = kv.split("=")
286                        value = v[0].strip() if v else True
287                        self.meta[k.strip()] = value
288                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
290    def append(self, arg_key: str, value: t.Any) -> None:
291        """
292        Appends value to arg_key if it's a list or sets it as a new list.
293
294        Args:
295            arg_key (str): name of the list expression arg
296            value (Any): value to append to the list
297        """
298        if not isinstance(self.args.get(arg_key), list):
299            self.args[arg_key] = []
300        self.args[arg_key].append(value)
301        self._set_parent(arg_key, value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set(self, arg_key: str, value: Any) -> None:
303    def set(self, arg_key: str, value: t.Any) -> None:
304        """
305        Sets arg_key to value.
306
307        Args:
308            arg_key: name of the expression arg.
309            value: value to set the arg to.
310        """
311        if value is None:
312            self.args.pop(arg_key, None)
313            return
314
315        self.args[arg_key] = value
316        self._set_parent(arg_key, value)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
depth: int
328    @property
329    def depth(self) -> int:
330        """
331        Returns the depth of this tree.
332        """
333        if self.parent:
334            return self.parent.depth + 1
335        return 0

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
337    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
338        """Yields the key and expression for all arguments, exploding list args."""
339        for k, vs in self.args.items():
340            if type(vs) is list:
341                for v in vs:
342                    if hasattr(v, "parent"):
343                        yield k, v
344            else:
345                if hasattr(vs, "parent"):
346                    yield k, vs

Yields the key and expression for all arguments, exploding list args.

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
348    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
349        """
350        Returns the first node in this tree which matches at least one of
351        the specified types.
352
353        Args:
354            expression_types: the expression type(s) to match.
355            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
356
357        Returns:
358            The node which matches the criteria or None if no such node was found.
359        """
360        return next(self.find_all(*expression_types, bfs=bfs), None)

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
362    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
363        """
364        Returns a generator object which visits all nodes in this tree and only
365        yields those that match at least one of the specified expression types.
366
367        Args:
368            expression_types: the expression type(s) to match.
369            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
370
371        Returns:
372            The generator object.
373        """
374        for expression, *_ in self.walk(bfs=bfs):
375            if isinstance(expression, expression_types):
376                yield expression

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
378    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
379        """
380        Returns a nearest parent matching expression_types.
381
382        Args:
383            expression_types: the expression type(s) to match.
384
385        Returns:
386            The parent node.
387        """
388        ancestor = self.parent
389        while ancestor and not isinstance(ancestor, expression_types):
390            ancestor = ancestor.parent
391        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]
393    @property
394    def parent_select(self) -> t.Optional[Select]:
395        """
396        Returns the parent select statement.
397        """
398        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
400    @property
401    def same_parent(self) -> bool:
402        """Returns if the parent is the same class as itself."""
403        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
405    def root(self) -> Expression:
406        """
407        Returns the root expression of this tree.
408        """
409        expression = self
410        while expression.parent:
411            expression = expression.parent
412        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
414    def walk(self, bfs=True, prune=None):
415        """
416        Returns a generator object which visits all nodes in this tree.
417
418        Args:
419            bfs (bool): if set to True the BFS traversal order will be applied,
420                otherwise the DFS traversal will be used instead.
421            prune ((node, parent, arg_key) -> bool): callable that returns True if
422                the generator should stop traversing this branch of the tree.
423
424        Returns:
425            the generator object.
426        """
427        if bfs:
428            yield from self.bfs(prune=prune)
429        else:
430            yield from self.dfs(prune=prune)

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs (bool): if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune ((node, parent, arg_key) -> bool): callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

def dfs(self, parent=None, key=None, prune=None):
432    def dfs(self, parent=None, key=None, prune=None):
433        """
434        Returns a generator object which visits all nodes in this tree in
435        the DFS (Depth-first) order.
436
437        Returns:
438            The generator object.
439        """
440        parent = parent or self.parent
441        yield self, parent, key
442        if prune and prune(self, parent, key):
443            return
444
445        for k, v in self.iter_expressions():
446            yield from v.dfs(self, k, prune)

Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.

Returns:

The generator object.

def bfs(self, prune=None):
448    def bfs(self, prune=None):
449        """
450        Returns a generator object which visits all nodes in this tree in
451        the BFS (Breadth-first) order.
452
453        Returns:
454            The generator object.
455        """
456        queue = deque([(self, self.parent, None)])
457
458        while queue:
459            item, parent, key = queue.popleft()
460
461            yield item, parent, key
462            if prune and prune(item, parent, key):
463                continue
464
465            for k, v in item.iter_expressions():
466                queue.append((v, item, k))

Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.

Returns:

The generator object.

def unnest(self):
468    def unnest(self):
469        """
470        Returns the first non parenthesis child or self.
471        """
472        expression = self
473        while type(expression) is Paren:
474            expression = expression.this
475        return expression

Returns the first non parenthesis child or self.

def unalias(self):
477    def unalias(self):
478        """
479        Returns the inner expression if this is an Alias.
480        """
481        if isinstance(self, Alias):
482            return self.this
483        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
485    def unnest_operands(self):
486        """
487        Returns unnested operands as a tuple.
488        """
489        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
491    def flatten(self, unnest=True):
492        """
493        Returns a generator which yields child nodes whose parents are the same class.
494
495        A AND B AND C -> [A, B, C]
496        """
497        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
498            if not type(node) is self.__class__:
499                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
507    def to_s(self) -> str:
508        """
509        Same as __repr__, but includes additional information which can be useful
510        for debugging, like empty or missing args and the AST nodes' object IDs.
511        """
512        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
514    def sql(self, dialect: DialectType = None, **opts) -> str:
515        """
516        Returns SQL string representation of this tree.
517
518        Args:
519            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
520            opts: other `sqlglot.generator.Generator` options.
521
522        Returns:
523            The SQL string.
524        """
525        from sqlglot.dialects import Dialect
526
527        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

Arguments:
  • dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
  • opts: other sqlglot.generator.Generator options.
Returns:

The SQL string.

def transform(self, fun, *args, copy=True, **kwargs):
529    def transform(self, fun, *args, copy=True, **kwargs):
530        """
531        Recursively visits all tree nodes (excluding already transformed ones)
532        and applies the given transformation function to each node.
533
534        Args:
535            fun (function): a function which takes a node as an argument and returns a
536                new transformed node or the same node without modifications. If the function
537                returns None, then the corresponding node will be removed from the syntax tree.
538            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
539                modified in place.
540
541        Returns:
542            The transformed tree.
543        """
544        node = self.copy() if copy else self
545        new_node = fun(node, *args, **kwargs)
546
547        if new_node is None or not isinstance(new_node, Expression):
548            return new_node
549        if new_node is not node:
550            new_node.parent = node.parent
551            return new_node
552
553        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
554        return new_node

Recursively visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun (function): a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy (bool): if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

def replace(self, expression):
562    def replace(self, expression):
563        """
564        Swap out this expression with a new expression.
565
566        For example::
567
568            >>> tree = Select().select("x").from_("tbl")
569            >>> tree.find(Column).replace(column("y"))
570            Column(
571              this=Identifier(this=y, quoted=False))
572            >>> tree.sql()
573            'SELECT y FROM tbl'
574
575        Args:
576            expression: new node
577
578        Returns:
579            The new expression or expressions.
580        """
581        if not self.parent:
582            return expression
583
584        parent = self.parent
585        self.parent = None
586
587        replace_children(parent, lambda child: expression if child is self else child)
588        return expression

Swap out this expression with a new expression.

For example::

>>> tree = Select().select("x").from_("tbl")
>>> tree.find(Column).replace(column("y"))
Column(
  this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
590    def pop(self: E) -> E:
591        """
592        Remove this expression from its AST.
593
594        Returns:
595            The popped expression.
596        """
597        self.replace(None)
598        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
600    def assert_is(self, type_: t.Type[E]) -> E:
601        """
602        Assert that this `Expression` is an instance of `type_`.
603
604        If it is NOT an instance of `type_`, this raises an assertion error.
605        Otherwise, this returns this expression.
606
607        Examples:
608            This is useful for type security in chained expressions:
609
610            >>> import sqlglot
611            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
612            'SELECT x, z FROM y'
613        """
614        assert isinstance(self, type_)
615        return self

Assert that this Expression is an instance of type_.

If it is NOT an instance of type_, this raises an assertion error. Otherwise, this returns this expression.

Examples:

This is useful for type security in chained expressions:

>>> import sqlglot
>>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
'SELECT x, z FROM y'
def error_messages(self, args: Optional[Sequence] = None) -> List[str]:
617    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
618        """
619        Checks if this expression is valid (e.g. all mandatory args are set).
620
621        Args:
622            args: a sequence of values that were used to instantiate a Func expression. This is used
623                to check that the provided arguments don't exceed the function argument limit.
624
625        Returns:
626            A list of error messages for all possible errors that were found.
627        """
628        errors: t.List[str] = []
629
630        for k in self.args:
631            if k not in self.arg_types:
632                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
633        for k, mandatory in self.arg_types.items():
634            v = self.args.get(k)
635            if mandatory and (v is None or (isinstance(v, list) and not v)):
636                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
637
638        if (
639            args
640            and isinstance(self, Func)
641            and len(args) > len(self.arg_types)
642            and not self.is_var_len_args
643        ):
644            errors.append(
645                f"The number of provided arguments ({len(args)}) is greater than "
646                f"the maximum number of supported arguments ({len(self.arg_types)})"
647            )
648
649        return errors

Checks if this expression is valid (e.g. all mandatory args are set).

Arguments:
  • args: a sequence of values that were used to instantiate a Func expression. This is used to check that the provided arguments don't exceed the function argument limit.
Returns:

A list of error messages for all possible errors that were found.

def dump(self):
651    def dump(self):
652        """
653        Dump this Expression to a JSON-serializable dict.
654        """
655        from sqlglot.serde import dump
656
657        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
659    @classmethod
660    def load(cls, obj):
661        """
662        Load a dict (as returned by `Expression.dump`) into an Expression instance.
663        """
664        from sqlglot.serde import load
665
666        return load(obj)

Load a dict (as returned by Expression.dump) into an Expression instance.

def and_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
668    def and_(
669        self,
670        *expressions: t.Optional[ExpOrStr],
671        dialect: DialectType = None,
672        copy: bool = True,
673        **opts,
674    ) -> Condition:
675        """
676        AND this condition with one or multiple expressions.
677
678        Example:
679            >>> condition("x=1").and_("y=1").sql()
680            'x = 1 AND y = 1'
681
682        Args:
683            *expressions: the SQL code strings to parse.
684                If an `Expression` instance is passed, it will be used as-is.
685            dialect: the dialect used to parse the input expression.
686            copy: whether or not to copy the involved expressions (only applies to Expressions).
687            opts: other options to use to parse the input expressions.
688
689        Returns:
690            The new And condition.
691        """
692        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1").and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
694    def or_(
695        self,
696        *expressions: t.Optional[ExpOrStr],
697        dialect: DialectType = None,
698        copy: bool = True,
699        **opts,
700    ) -> Condition:
701        """
702        OR this condition with one or multiple expressions.
703
704        Example:
705            >>> condition("x=1").or_("y=1").sql()
706            'x = 1 OR y = 1'
707
708        Args:
709            *expressions: the SQL code strings to parse.
710                If an `Expression` instance is passed, it will be used as-is.
711            dialect: the dialect used to parse the input expression.
712            copy: whether or not to copy the involved expressions (only applies to Expressions).
713            opts: other options to use to parse the input expressions.
714
715        Returns:
716            The new Or condition.
717        """
718        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1").or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
720    def not_(self, copy: bool = True):
721        """
722        Wrap this condition with NOT.
723
724        Example:
725            >>> condition("x=1").not_().sql()
726            'NOT x = 1'
727
728        Args:
729            copy: whether or not to copy this object.
730
731        Returns:
732            The new Not instance.
733        """
734        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether or not to copy this object.
Returns:

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
736    def as_(
737        self,
738        alias: str | Identifier,
739        quoted: t.Optional[bool] = None,
740        dialect: DialectType = None,
741        copy: bool = True,
742        **opts,
743    ) -> Alias:
744        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
769    def isin(
770        self,
771        *expressions: t.Any,
772        query: t.Optional[ExpOrStr] = None,
773        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
774        copy: bool = True,
775        **opts,
776    ) -> In:
777        return In(
778            this=maybe_copy(self, copy),
779            expressions=[convert(e, copy=copy) for e in expressions],
780            query=maybe_parse(query, copy=copy, **opts) if query else None,
781            unnest=(
782                Unnest(
783                    expressions=[
784                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
785                        for e in ensure_list(unnest)
786                    ]
787                )
788                if unnest
789                else None
790            ),
791        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
793    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
794        return Between(
795            this=maybe_copy(self, copy),
796            low=convert(low, copy=copy, **opts),
797            high=convert(high, copy=copy, **opts),
798        )
def is_( self, other: Union[str, Expression]) -> Is:
800    def is_(self, other: ExpOrStr) -> Is:
801        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
803    def like(self, other: ExpOrStr) -> Like:
804        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
806    def ilike(self, other: ExpOrStr) -> ILike:
807        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
809    def eq(self, other: t.Any) -> EQ:
810        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
812    def neq(self, other: t.Any) -> NEQ:
813        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
815    def rlike(self, other: ExpOrStr) -> RegexpLike:
816        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
818    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
819        div = self._binop(Div, other)
820        div.args["typed"] = typed
821        div.args["safe"] = safe
822        return div
def desc(self, nulls_first: bool = False) -> Ordered:
824    def desc(self, nulls_first: bool = False) -> Ordered:
825        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
908class Condition(Expression):
909    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

key = 'condition'
class Predicate(Condition):
912class Predicate(Condition):
913    """Relationships like x = y, x > 1, x >= y."""

Relationships like x = y, x > 1, x >= y.

key = 'predicate'
class DerivedTable(Expression):
916class DerivedTable(Expression):
917    @property
918    def selects(self) -> t.List[Expression]:
919        return self.this.selects if isinstance(self.this, Subqueryable) else []
920
921    @property
922    def named_selects(self) -> t.List[str]:
923        return [select.output_name for select in self.selects]
selects: List[Expression]
917    @property
918    def selects(self) -> t.List[Expression]:
919        return self.this.selects if isinstance(self.this, Subqueryable) else []
named_selects: List[str]
921    @property
922    def named_selects(self) -> t.List[str]:
923        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Unionable(Expression):
926class Unionable(Expression):
927    def union(
928        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
929    ) -> Union:
930        """
931        Builds a UNION expression.
932
933        Example:
934            >>> import sqlglot
935            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
936            'SELECT * FROM foo UNION SELECT * FROM bla'
937
938        Args:
939            expression: the SQL code string.
940                If an `Expression` instance is passed, it will be used as-is.
941            distinct: set the DISTINCT flag if and only if this is true.
942            dialect: the dialect used to parse the input expression.
943            opts: other options to use to parse the input expressions.
944
945        Returns:
946            The new Union expression.
947        """
948        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
949
950    def intersect(
951        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
952    ) -> Unionable:
953        """
954        Builds an INTERSECT expression.
955
956        Example:
957            >>> import sqlglot
958            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
959            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
960
961        Args:
962            expression: the SQL code string.
963                If an `Expression` instance is passed, it will be used as-is.
964            distinct: set the DISTINCT flag if and only if this is true.
965            dialect: the dialect used to parse the input expression.
966            opts: other options to use to parse the input expressions.
967
968        Returns:
969            The new Intersect expression.
970        """
971        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
972
973    def except_(
974        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
975    ) -> Unionable:
976        """
977        Builds an EXCEPT expression.
978
979        Example:
980            >>> import sqlglot
981            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
982            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
983
984        Args:
985            expression: the SQL code string.
986                If an `Expression` instance is passed, it will be used as-is.
987            distinct: set the DISTINCT flag if and only if this is true.
988            dialect: the dialect used to parse the input expression.
989            opts: other options to use to parse the input expressions.
990
991        Returns:
992            The new Except expression.
993        """
994        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def union( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
927    def union(
928        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
929    ) -> Union:
930        """
931        Builds a UNION expression.
932
933        Example:
934            >>> import sqlglot
935            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
936            'SELECT * FROM foo UNION SELECT * FROM bla'
937
938        Args:
939            expression: the SQL code string.
940                If an `Expression` instance is passed, it will be used as-is.
941            distinct: set the DISTINCT flag if and only if this is true.
942            dialect: the dialect used to parse the input expression.
943            opts: other options to use to parse the input expressions.
944
945        Returns:
946            The new Union expression.
947        """
948        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **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:
  • expression: the SQL code string. If an Expression instance is passed, it 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, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Unionable:
950    def intersect(
951        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
952    ) -> Unionable:
953        """
954        Builds an INTERSECT expression.
955
956        Example:
957            >>> import sqlglot
958            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
959            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
960
961        Args:
962            expression: the SQL code string.
963                If an `Expression` instance is passed, it will be used as-is.
964            distinct: set the DISTINCT flag if and only if this is true.
965            dialect: the dialect used to parse the input expression.
966            opts: other options to use to parse the input expressions.
967
968        Returns:
969            The new Intersect expression.
970        """
971        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **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:
  • expression: the SQL code string. If an Expression instance is passed, it 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, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Unionable:
973    def except_(
974        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
975    ) -> Unionable:
976        """
977        Builds an EXCEPT expression.
978
979        Example:
980            >>> import sqlglot
981            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
982            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
983
984        Args:
985            expression: the SQL code string.
986                If an `Expression` instance is passed, it will be used as-is.
987            distinct: set the DISTINCT flag if and only if this is true.
988            dialect: the dialect used to parse the input expression.
989            opts: other options to use to parse the input expressions.
990
991        Returns:
992            The new Except expression.
993        """
994        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **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:
  • expression: the SQL code string. If an Expression instance is passed, it 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 = 'unionable'
class UDTF(DerivedTable, Unionable):
 997class UDTF(DerivedTable, Unionable):
 998    @property
 999    def selects(self) -> t.List[Expression]:
1000        alias = self.args.get("alias")
1001        return alias.columns if alias else []
selects: List[Expression]
 998    @property
 999    def selects(self) -> t.List[Expression]:
1000        alias = self.args.get("alias")
1001        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1004class Cache(Expression):
1005    arg_types = {
1006        "this": True,
1007        "lazy": False,
1008        "options": False,
1009        "expression": False,
1010    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1013class Uncache(Expression):
1014    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1017class Refresh(Expression):
1018    pass
key = 'refresh'
class DDL(Expression):
1021class DDL(Expression):
1022    @property
1023    def ctes(self):
1024        with_ = self.args.get("with")
1025        if not with_:
1026            return []
1027        return with_.expressions
1028
1029    @property
1030    def named_selects(self) -> t.List[str]:
1031        if isinstance(self.expression, Subqueryable):
1032            return self.expression.named_selects
1033        return []
1034
1035    @property
1036    def selects(self) -> t.List[Expression]:
1037        if isinstance(self.expression, Subqueryable):
1038            return self.expression.selects
1039        return []
ctes
1022    @property
1023    def ctes(self):
1024        with_ = self.args.get("with")
1025        if not with_:
1026            return []
1027        return with_.expressions
named_selects: List[str]
1029    @property
1030    def named_selects(self) -> t.List[str]:
1031        if isinstance(self.expression, Subqueryable):
1032            return self.expression.named_selects
1033        return []
selects: List[Expression]
1035    @property
1036    def selects(self) -> t.List[Expression]:
1037        if isinstance(self.expression, Subqueryable):
1038            return self.expression.selects
1039        return []
key = 'ddl'
class DML(Expression):
1042class DML(Expression):
1043    def returning(
1044        self,
1045        expression: ExpOrStr,
1046        dialect: DialectType = None,
1047        copy: bool = True,
1048        **opts,
1049    ) -> DML:
1050        """
1051        Set the RETURNING expression. Not supported by all dialects.
1052
1053        Example:
1054            >>> delete("tbl").returning("*", dialect="postgres").sql()
1055            'DELETE FROM tbl RETURNING *'
1056
1057        Args:
1058            expression: the SQL code strings to parse.
1059                If an `Expression` instance is passed, it will be used as-is.
1060            dialect: the dialect used to parse the input expressions.
1061            copy: if `False`, modify this expression instance in-place.
1062            opts: other options to use to parse the input expressions.
1063
1064        Returns:
1065            Delete: the modified expression.
1066        """
1067        return _apply_builder(
1068            expression=expression,
1069            instance=self,
1070            arg="returning",
1071            prefix="RETURNING",
1072            dialect=dialect,
1073            copy=copy,
1074            into=Returning,
1075            **opts,
1076        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> DML:
1043    def returning(
1044        self,
1045        expression: ExpOrStr,
1046        dialect: DialectType = None,
1047        copy: bool = True,
1048        **opts,
1049    ) -> DML:
1050        """
1051        Set the RETURNING expression. Not supported by all dialects.
1052
1053        Example:
1054            >>> delete("tbl").returning("*", dialect="postgres").sql()
1055            'DELETE FROM tbl RETURNING *'
1056
1057        Args:
1058            expression: the SQL code strings to parse.
1059                If an `Expression` instance is passed, it will be used as-is.
1060            dialect: the dialect used to parse the input expressions.
1061            copy: if `False`, modify this expression instance in-place.
1062            opts: other options to use to parse the input expressions.
1063
1064        Returns:
1065            Delete: the modified expression.
1066        """
1067        return _apply_builder(
1068            expression=expression,
1069            instance=self,
1070            arg="returning",
1071            prefix="RETURNING",
1072            dialect=dialect,
1073            copy=copy,
1074            into=Returning,
1075            **opts,
1076        )

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • 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:

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1079class Create(DDL):
1080    arg_types = {
1081        "with": False,
1082        "this": True,
1083        "kind": True,
1084        "expression": False,
1085        "exists": False,
1086        "properties": False,
1087        "replace": False,
1088        "unique": False,
1089        "indexes": False,
1090        "no_schema_binding": False,
1091        "begin": False,
1092        "end": False,
1093        "clone": False,
1094    }
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False}
key = 'create'
class Clone(Expression):
1100class Clone(Expression):
1101    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1104class Describe(Expression):
1105    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'extended': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1108class Kill(Expression):
1109    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1112class Pragma(Expression):
1113    pass
key = 'pragma'
class Set(Expression):
1116class Set(Expression):
1117    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1120class Heredoc(Expression):
1121    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1124class SetItem(Expression):
1125    arg_types = {
1126        "this": False,
1127        "expressions": False,
1128        "kind": False,
1129        "collate": False,  # MySQL SET NAMES statement
1130        "global": False,
1131    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1134class Show(Expression):
1135    arg_types = {
1136        "this": True,
1137        "terse": False,
1138        "target": False,
1139        "offset": False,
1140        "starts_with": False,
1141        "limit": False,
1142        "from": False,
1143        "like": False,
1144        "where": False,
1145        "db": False,
1146        "scope": False,
1147        "scope_kind": False,
1148        "full": False,
1149        "mutex": False,
1150        "query": False,
1151        "channel": False,
1152        "global": False,
1153        "log": False,
1154        "position": False,
1155        "types": False,
1156    }
arg_types = {'this': True, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False}
key = 'show'
class UserDefinedFunction(Expression):
1159class UserDefinedFunction(Expression):
1160    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1163class CharacterSet(Expression):
1164    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1167class With(Expression):
1168    arg_types = {"expressions": True, "recursive": False}
1169
1170    @property
1171    def recursive(self) -> bool:
1172        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1170    @property
1171    def recursive(self) -> bool:
1172        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1175class WithinGroup(Expression):
1176    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1181class CTE(DerivedTable):
1182    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1185class TableAlias(Expression):
1186    arg_types = {"this": False, "columns": False}
1187
1188    @property
1189    def columns(self):
1190        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1188    @property
1189    def columns(self):
1190        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1193class BitString(Condition):
1194    pass
key = 'bitstring'
class HexString(Condition):
1197class HexString(Condition):
1198    pass
key = 'hexstring'
class ByteString(Condition):
1201class ByteString(Condition):
1202    pass
key = 'bytestring'
class RawString(Condition):
1205class RawString(Condition):
1206    pass
key = 'rawstring'
class UnicodeString(Condition):
1209class UnicodeString(Condition):
1210    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1213class Column(Condition):
1214    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1215
1216    @property
1217    def table(self) -> str:
1218        return self.text("table")
1219
1220    @property
1221    def db(self) -> str:
1222        return self.text("db")
1223
1224    @property
1225    def catalog(self) -> str:
1226        return self.text("catalog")
1227
1228    @property
1229    def output_name(self) -> str:
1230        return self.name
1231
1232    @property
1233    def parts(self) -> t.List[Identifier]:
1234        """Return the parts of a column in order catalog, db, table, name."""
1235        return [
1236            t.cast(Identifier, self.args[part])
1237            for part in ("catalog", "db", "table", "this")
1238            if self.args.get(part)
1239        ]
1240
1241    def to_dot(self) -> Dot | Identifier:
1242        """Converts the column into a dot expression."""
1243        parts = self.parts
1244        parent = self.parent
1245
1246        while parent:
1247            if isinstance(parent, Dot):
1248                parts.append(parent.expression)
1249            parent = parent.parent
1250
1251        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1216    @property
1217    def table(self) -> str:
1218        return self.text("table")
db: str
1220    @property
1221    def db(self) -> str:
1222        return self.text("db")
catalog: str
1224    @property
1225    def catalog(self) -> str:
1226        return self.text("catalog")
output_name: str
1228    @property
1229    def output_name(self) -> str:
1230        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1232    @property
1233    def parts(self) -> t.List[Identifier]:
1234        """Return the parts of a column in order catalog, db, table, name."""
1235        return [
1236            t.cast(Identifier, self.args[part])
1237            for part in ("catalog", "db", "table", "this")
1238            if self.args.get(part)
1239        ]

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

def to_dot(self) -> Dot | Identifier:
1241    def to_dot(self) -> Dot | Identifier:
1242        """Converts the column into a dot expression."""
1243        parts = self.parts
1244        parent = self.parent
1245
1246        while parent:
1247            if isinstance(parent, Dot):
1248                parts.append(parent.expression)
1249            parent = parent.parent
1250
1251        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1254class ColumnPosition(Expression):
1255    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1258class ColumnDef(Expression):
1259    arg_types = {
1260        "this": True,
1261        "kind": False,
1262        "constraints": False,
1263        "exists": False,
1264        "position": False,
1265    }
1266
1267    @property
1268    def constraints(self) -> t.List[ColumnConstraint]:
1269        return self.args.get("constraints") or []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1267    @property
1268    def constraints(self) -> t.List[ColumnConstraint]:
1269        return self.args.get("constraints") or []
key = 'columndef'
class AlterColumn(Expression):
1272class AlterColumn(Expression):
1273    arg_types = {
1274        "this": True,
1275        "dtype": False,
1276        "collate": False,
1277        "using": False,
1278        "default": False,
1279        "drop": False,
1280        "comment": False,
1281    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1284class RenameColumn(Expression):
1285    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1288class RenameTable(Expression):
1289    pass
key = 'renametable'
class SwapTable(Expression):
1292class SwapTable(Expression):
1293    pass
key = 'swaptable'
class Comment(Expression):
1296class Comment(Expression):
1297    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False}
key = 'comment'
class Comprehension(Expression):
1300class Comprehension(Expression):
1301    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
arg_types = {'this': True, 'expression': True, 'iterator': True, 'condition': False}
key = 'comprehension'
class MergeTreeTTLAction(Expression):
1305class MergeTreeTTLAction(Expression):
1306    arg_types = {
1307        "this": True,
1308        "delete": False,
1309        "recompress": False,
1310        "to_disk": False,
1311        "to_volume": False,
1312    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1316class MergeTreeTTL(Expression):
1317    arg_types = {
1318        "expressions": True,
1319        "where": False,
1320        "group": False,
1321        "aggregates": False,
1322    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1326class IndexConstraintOption(Expression):
1327    arg_types = {
1328        "key_block_size": False,
1329        "using": False,
1330        "parser": False,
1331        "comment": False,
1332        "visible": False,
1333        "engine_attr": False,
1334        "secondary_engine_attr": False,
1335    }
arg_types = {'key_block_size': False, 'using': False, 'parser': False, 'comment': False, 'visible': False, 'engine_attr': False, 'secondary_engine_attr': False}
key = 'indexconstraintoption'
class ColumnConstraint(Expression):
1338class ColumnConstraint(Expression):
1339    arg_types = {"this": False, "kind": True}
1340
1341    @property
1342    def kind(self) -> ColumnConstraintKind:
1343        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1341    @property
1342    def kind(self) -> ColumnConstraintKind:
1343        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1346class ColumnConstraintKind(Expression):
1347    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1350class AutoIncrementColumnConstraint(ColumnConstraintKind):
1351    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1354class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1355    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1358class CaseSpecificColumnConstraint(ColumnConstraintKind):
1359    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1362class CharacterSetColumnConstraint(ColumnConstraintKind):
1363    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1366class CheckColumnConstraint(ColumnConstraintKind):
1367    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1370class ClusteredColumnConstraint(ColumnConstraintKind):
1371    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1374class CollateColumnConstraint(ColumnConstraintKind):
1375    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1378class CommentColumnConstraint(ColumnConstraintKind):
1379    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1382class CompressColumnConstraint(ColumnConstraintKind):
1383    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1386class DateFormatColumnConstraint(ColumnConstraintKind):
1387    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1390class DefaultColumnConstraint(ColumnConstraintKind):
1391    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1394class EncodeColumnConstraint(ColumnConstraintKind):
1395    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1398class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1399    # this: True -> ALWAYS, this: False -> BY DEFAULT
1400    arg_types = {
1401        "this": False,
1402        "expression": False,
1403        "on_null": False,
1404        "start": False,
1405        "increment": False,
1406        "minvalue": False,
1407        "maxvalue": False,
1408        "cycle": False,
1409    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1412class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1413    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1417class IndexColumnConstraint(ColumnConstraintKind):
1418    arg_types = {
1419        "this": False,
1420        "schema": True,
1421        "kind": False,
1422        "index_type": False,
1423        "options": False,
1424    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1427class InlineLengthColumnConstraint(ColumnConstraintKind):
1428    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1431class NonClusteredColumnConstraint(ColumnConstraintKind):
1432    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1435class NotForReplicationColumnConstraint(ColumnConstraintKind):
1436    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1439class NotNullColumnConstraint(ColumnConstraintKind):
1440    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1444class OnUpdateColumnConstraint(ColumnConstraintKind):
1445    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1449class TransformColumnConstraint(ColumnConstraintKind):
1450    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1453class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1454    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1457class TitleColumnConstraint(ColumnConstraintKind):
1458    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1461class UniqueColumnConstraint(ColumnConstraintKind):
1462    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1465class UppercaseColumnConstraint(ColumnConstraintKind):
1466    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1469class PathColumnConstraint(ColumnConstraintKind):
1470    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1475class ComputedColumnConstraint(ColumnConstraintKind):
1476    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1479class Constraint(Expression):
1480    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1483class Delete(DML):
1484    arg_types = {
1485        "with": False,
1486        "this": False,
1487        "using": False,
1488        "where": False,
1489        "returning": False,
1490        "limit": False,
1491        "tables": False,  # Multiple-Table Syntax (MySQL)
1492    }
1493
1494    def delete(
1495        self,
1496        table: ExpOrStr,
1497        dialect: DialectType = None,
1498        copy: bool = True,
1499        **opts,
1500    ) -> Delete:
1501        """
1502        Create a DELETE expression or replace the table on an existing DELETE expression.
1503
1504        Example:
1505            >>> delete("tbl").sql()
1506            'DELETE FROM tbl'
1507
1508        Args:
1509            table: the table from which to delete.
1510            dialect: the dialect used to parse the input expression.
1511            copy: if `False`, modify this expression instance in-place.
1512            opts: other options to use to parse the input expressions.
1513
1514        Returns:
1515            Delete: the modified expression.
1516        """
1517        return _apply_builder(
1518            expression=table,
1519            instance=self,
1520            arg="this",
1521            dialect=dialect,
1522            into=Table,
1523            copy=copy,
1524            **opts,
1525        )
1526
1527    def where(
1528        self,
1529        *expressions: t.Optional[ExpOrStr],
1530        append: bool = True,
1531        dialect: DialectType = None,
1532        copy: bool = True,
1533        **opts,
1534    ) -> Delete:
1535        """
1536        Append to or set the WHERE expressions.
1537
1538        Example:
1539            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1540            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1541
1542        Args:
1543            *expressions: the SQL code strings to parse.
1544                If an `Expression` instance is passed, it will be used as-is.
1545                Multiple expressions are combined with an AND operator.
1546            append: if `True`, AND the new expressions to any existing expression.
1547                Otherwise, this resets the expression.
1548            dialect: the dialect used to parse the input expressions.
1549            copy: if `False`, modify this expression instance in-place.
1550            opts: other options to use to parse the input expressions.
1551
1552        Returns:
1553            Delete: the modified expression.
1554        """
1555        return _apply_conjunction_builder(
1556            *expressions,
1557            instance=self,
1558            arg="where",
1559            append=append,
1560            into=Where,
1561            dialect=dialect,
1562            copy=copy,
1563            **opts,
1564        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1494    def delete(
1495        self,
1496        table: ExpOrStr,
1497        dialect: DialectType = None,
1498        copy: bool = True,
1499        **opts,
1500    ) -> Delete:
1501        """
1502        Create a DELETE expression or replace the table on an existing DELETE expression.
1503
1504        Example:
1505            >>> delete("tbl").sql()
1506            'DELETE FROM tbl'
1507
1508        Args:
1509            table: the table from which to delete.
1510            dialect: the dialect used to parse the input expression.
1511            copy: if `False`, modify this expression instance in-place.
1512            opts: other options to use to parse the input expressions.
1513
1514        Returns:
1515            Delete: the modified expression.
1516        """
1517        return _apply_builder(
1518            expression=table,
1519            instance=self,
1520            arg="this",
1521            dialect=dialect,
1522            into=Table,
1523            copy=copy,
1524            **opts,
1525        )

Create a DELETE expression or replace the table on an existing DELETE expression.

Example:
>>> delete("tbl").sql()
'DELETE FROM tbl'
Arguments:
  • table: the table from which to delete.
  • 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:

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1527    def where(
1528        self,
1529        *expressions: t.Optional[ExpOrStr],
1530        append: bool = True,
1531        dialect: DialectType = None,
1532        copy: bool = True,
1533        **opts,
1534    ) -> Delete:
1535        """
1536        Append to or set the WHERE expressions.
1537
1538        Example:
1539            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1540            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1541
1542        Args:
1543            *expressions: the SQL code strings to parse.
1544                If an `Expression` instance is passed, it will be used as-is.
1545                Multiple expressions are combined with an AND operator.
1546            append: if `True`, AND the new expressions to any existing expression.
1547                Otherwise, this resets the expression.
1548            dialect: the dialect used to parse the input expressions.
1549            copy: if `False`, modify this expression instance in-place.
1550            opts: other options to use to parse the input expressions.
1551
1552        Returns:
1553            Delete: the modified expression.
1554        """
1555        return _apply_conjunction_builder(
1556            *expressions,
1557            instance=self,
1558            arg="where",
1559            append=append,
1560            into=Where,
1561            dialect=dialect,
1562            copy=copy,
1563            **opts,
1564        )

Append to or set the WHERE expressions.

Example:
>>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
"DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression 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:

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
1567class Drop(Expression):
1568    arg_types = {
1569        "this": False,
1570        "kind": False,
1571        "exists": False,
1572        "temporary": False,
1573        "materialized": False,
1574        "cascade": False,
1575        "constraints": False,
1576        "purge": False,
1577    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1580class Filter(Expression):
1581    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1584class Check(Expression):
1585    pass
key = 'check'
class Connect(Expression):
1589class Connect(Expression):
1590    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1593class Prior(Expression):
1594    pass
key = 'prior'
class Directory(Expression):
1597class Directory(Expression):
1598    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1599    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1602class ForeignKey(Expression):
1603    arg_types = {
1604        "expressions": True,
1605        "reference": False,
1606        "delete": False,
1607        "update": False,
1608    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1611class ColumnPrefix(Expression):
1612    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1615class PrimaryKey(Expression):
1616    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1621class Into(Expression):
1622    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1625class From(Expression):
1626    @property
1627    def name(self) -> str:
1628        return self.this.name
1629
1630    @property
1631    def alias_or_name(self) -> str:
1632        return self.this.alias_or_name
name: str
1626    @property
1627    def name(self) -> str:
1628        return self.this.name
alias_or_name: str
1630    @property
1631    def alias_or_name(self) -> str:
1632        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1635class Having(Expression):
1636    pass
key = 'having'
class Hint(Expression):
1639class Hint(Expression):
1640    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1643class JoinHint(Expression):
1644    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1647class Identifier(Expression):
1648    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1649
1650    @property
1651    def quoted(self) -> bool:
1652        return bool(self.args.get("quoted"))
1653
1654    @property
1655    def hashable_args(self) -> t.Any:
1656        return (self.this, self.quoted)
1657
1658    @property
1659    def output_name(self) -> str:
1660        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1650    @property
1651    def quoted(self) -> bool:
1652        return bool(self.args.get("quoted"))
hashable_args: Any
1654    @property
1655    def hashable_args(self) -> t.Any:
1656        return (self.this, self.quoted)
output_name: str
1658    @property
1659    def output_name(self) -> str:
1660        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
1664class Opclass(Expression):
1665    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1668class Index(Expression):
1669    arg_types = {
1670        "this": False,
1671        "table": False,
1672        "using": False,
1673        "where": False,
1674        "columns": False,
1675        "unique": False,
1676        "primary": False,
1677        "amp": False,  # teradata
1678        "include": False,
1679        "partition_by": False,  # teradata
1680        "where": False,  # postgres partial indexes
1681    }
arg_types = {'this': False, 'table': False, 'using': False, 'where': False, 'columns': False, 'unique': False, 'primary': False, 'amp': False, 'include': False, 'partition_by': False}
key = 'index'
class Insert(DDL, DML):
1684class Insert(DDL, DML):
1685    arg_types = {
1686        "with": False,
1687        "this": True,
1688        "expression": False,
1689        "conflict": False,
1690        "returning": False,
1691        "overwrite": False,
1692        "exists": False,
1693        "partition": False,
1694        "alternative": False,
1695        "where": False,
1696        "ignore": False,
1697        "by_name": False,
1698    }
1699
1700    def with_(
1701        self,
1702        alias: ExpOrStr,
1703        as_: ExpOrStr,
1704        recursive: t.Optional[bool] = None,
1705        append: bool = True,
1706        dialect: DialectType = None,
1707        copy: bool = True,
1708        **opts,
1709    ) -> Insert:
1710        """
1711        Append to or set the common table expressions.
1712
1713        Example:
1714            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1715            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1716
1717        Args:
1718            alias: the SQL code string to parse as the table name.
1719                If an `Expression` instance is passed, this is used as-is.
1720            as_: the SQL code string to parse as the table expression.
1721                If an `Expression` instance is passed, it will be used as-is.
1722            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1723            append: if `True`, add to any existing expressions.
1724                Otherwise, this resets the expressions.
1725            dialect: the dialect used to parse the input expression.
1726            copy: if `False`, modify this expression instance in-place.
1727            opts: other options to use to parse the input expressions.
1728
1729        Returns:
1730            The modified expression.
1731        """
1732        return _apply_cte_builder(
1733            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1734        )
arg_types = {'with': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
1700    def with_(
1701        self,
1702        alias: ExpOrStr,
1703        as_: ExpOrStr,
1704        recursive: t.Optional[bool] = None,
1705        append: bool = True,
1706        dialect: DialectType = None,
1707        copy: bool = True,
1708        **opts,
1709    ) -> Insert:
1710        """
1711        Append to or set the common table expressions.
1712
1713        Example:
1714            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1715            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1716
1717        Args:
1718            alias: the SQL code string to parse as the table name.
1719                If an `Expression` instance is passed, this is used as-is.
1720            as_: the SQL code string to parse as the table expression.
1721                If an `Expression` instance is passed, it will be used as-is.
1722            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1723            append: if `True`, add to any existing expressions.
1724                Otherwise, this resets the expressions.
1725            dialect: the dialect used to parse the input expression.
1726            copy: if `False`, modify this expression instance in-place.
1727            opts: other options to use to parse the input expressions.
1728
1729        Returns:
1730            The modified expression.
1731        """
1732        return _apply_cte_builder(
1733            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1734        )

Append to or set the common table expressions.

Example:
>>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • 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.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

key = 'insert'
class OnConflict(Expression):
1737class OnConflict(Expression):
1738    arg_types = {
1739        "duplicate": False,
1740        "expressions": False,
1741        "nothing": False,
1742        "key": False,
1743        "constraint": False,
1744    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1747class Returning(Expression):
1748    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1752class Introducer(Expression):
1753    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1757class National(Expression):
1758    pass
key = 'national'
class LoadData(Expression):
1761class LoadData(Expression):
1762    arg_types = {
1763        "this": True,
1764        "local": False,
1765        "overwrite": False,
1766        "inpath": True,
1767        "partition": False,
1768        "input_format": False,
1769        "serde": False,
1770    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1773class Partition(Expression):
1774    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1777class Fetch(Expression):
1778    arg_types = {
1779        "direction": False,
1780        "count": False,
1781        "percent": False,
1782        "with_ties": False,
1783    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1786class Group(Expression):
1787    arg_types = {
1788        "expressions": False,
1789        "grouping_sets": False,
1790        "cube": False,
1791        "rollup": False,
1792        "totals": False,
1793        "all": False,
1794    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1797class Lambda(Expression):
1798    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1801class Limit(Expression):
1802    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1805class Literal(Condition):
1806    arg_types = {"this": True, "is_string": True}
1807
1808    @property
1809    def hashable_args(self) -> t.Any:
1810        return (self.this, self.args.get("is_string"))
1811
1812    @classmethod
1813    def number(cls, number) -> Literal:
1814        return cls(this=str(number), is_string=False)
1815
1816    @classmethod
1817    def string(cls, string) -> Literal:
1818        return cls(this=str(string), is_string=True)
1819
1820    @property
1821    def output_name(self) -> str:
1822        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1808    @property
1809    def hashable_args(self) -> t.Any:
1810        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1812    @classmethod
1813    def number(cls, number) -> Literal:
1814        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1816    @classmethod
1817    def string(cls, string) -> Literal:
1818        return cls(this=str(string), is_string=True)
output_name: str
1820    @property
1821    def output_name(self) -> str:
1822        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'literal'
class Join(Expression):
1825class Join(Expression):
1826    arg_types = {
1827        "this": True,
1828        "on": False,
1829        "side": False,
1830        "kind": False,
1831        "using": False,
1832        "method": False,
1833        "global": False,
1834        "hint": False,
1835    }
1836
1837    @property
1838    def method(self) -> str:
1839        return self.text("method").upper()
1840
1841    @property
1842    def kind(self) -> str:
1843        return self.text("kind").upper()
1844
1845    @property
1846    def side(self) -> str:
1847        return self.text("side").upper()
1848
1849    @property
1850    def hint(self) -> str:
1851        return self.text("hint").upper()
1852
1853    @property
1854    def alias_or_name(self) -> str:
1855        return self.this.alias_or_name
1856
1857    def on(
1858        self,
1859        *expressions: t.Optional[ExpOrStr],
1860        append: bool = True,
1861        dialect: DialectType = None,
1862        copy: bool = True,
1863        **opts,
1864    ) -> Join:
1865        """
1866        Append to or set the ON expressions.
1867
1868        Example:
1869            >>> import sqlglot
1870            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1871            'JOIN x ON y = 1'
1872
1873        Args:
1874            *expressions: the SQL code strings to parse.
1875                If an `Expression` instance is passed, it will be used as-is.
1876                Multiple expressions are combined with an AND operator.
1877            append: if `True`, AND the new expressions to any existing expression.
1878                Otherwise, this resets the expression.
1879            dialect: the dialect used to parse the input expressions.
1880            copy: if `False`, modify this expression instance in-place.
1881            opts: other options to use to parse the input expressions.
1882
1883        Returns:
1884            The modified Join expression.
1885        """
1886        join = _apply_conjunction_builder(
1887            *expressions,
1888            instance=self,
1889            arg="on",
1890            append=append,
1891            dialect=dialect,
1892            copy=copy,
1893            **opts,
1894        )
1895
1896        if join.kind == "CROSS":
1897            join.set("kind", None)
1898
1899        return join
1900
1901    def using(
1902        self,
1903        *expressions: t.Optional[ExpOrStr],
1904        append: bool = True,
1905        dialect: DialectType = None,
1906        copy: bool = True,
1907        **opts,
1908    ) -> Join:
1909        """
1910        Append to or set the USING expressions.
1911
1912        Example:
1913            >>> import sqlglot
1914            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1915            'JOIN x USING (foo, bla)'
1916
1917        Args:
1918            *expressions: the SQL code strings to parse.
1919                If an `Expression` instance is passed, it will be used as-is.
1920            append: if `True`, concatenate the new expressions to the existing "using" list.
1921                Otherwise, this resets the expression.
1922            dialect: the dialect used to parse the input expressions.
1923            copy: if `False`, modify this expression instance in-place.
1924            opts: other options to use to parse the input expressions.
1925
1926        Returns:
1927            The modified Join expression.
1928        """
1929        join = _apply_list_builder(
1930            *expressions,
1931            instance=self,
1932            arg="using",
1933            append=append,
1934            dialect=dialect,
1935            copy=copy,
1936            **opts,
1937        )
1938
1939        if join.kind == "CROSS":
1940            join.set("kind", None)
1941
1942        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1837    @property
1838    def method(self) -> str:
1839        return self.text("method").upper()
kind: str
1841    @property
1842    def kind(self) -> str:
1843        return self.text("kind").upper()
side: str
1845    @property
1846    def side(self) -> str:
1847        return self.text("side").upper()
hint: str
1849    @property
1850    def hint(self) -> str:
1851        return self.text("hint").upper()
alias_or_name: str
1853    @property
1854    def alias_or_name(self) -> str:
1855        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
1857    def on(
1858        self,
1859        *expressions: t.Optional[ExpOrStr],
1860        append: bool = True,
1861        dialect: DialectType = None,
1862        copy: bool = True,
1863        **opts,
1864    ) -> Join:
1865        """
1866        Append to or set the ON expressions.
1867
1868        Example:
1869            >>> import sqlglot
1870            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1871            'JOIN x ON y = 1'
1872
1873        Args:
1874            *expressions: the SQL code strings to parse.
1875                If an `Expression` instance is passed, it will be used as-is.
1876                Multiple expressions are combined with an AND operator.
1877            append: if `True`, AND the new expressions to any existing expression.
1878                Otherwise, this resets the expression.
1879            dialect: the dialect used to parse the input expressions.
1880            copy: if `False`, modify this expression instance in-place.
1881            opts: other options to use to parse the input expressions.
1882
1883        Returns:
1884            The modified Join expression.
1885        """
1886        join = _apply_conjunction_builder(
1887            *expressions,
1888            instance=self,
1889            arg="on",
1890            append=append,
1891            dialect=dialect,
1892            copy=copy,
1893            **opts,
1894        )
1895
1896        if join.kind == "CROSS":
1897            join.set("kind", None)
1898
1899        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 Expression 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[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
1901    def using(
1902        self,
1903        *expressions: t.Optional[ExpOrStr],
1904        append: bool = True,
1905        dialect: DialectType = None,
1906        copy: bool = True,
1907        **opts,
1908    ) -> Join:
1909        """
1910        Append to or set the USING expressions.
1911
1912        Example:
1913            >>> import sqlglot
1914            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1915            'JOIN x USING (foo, bla)'
1916
1917        Args:
1918            *expressions: the SQL code strings to parse.
1919                If an `Expression` instance is passed, it will be used as-is.
1920            append: if `True`, concatenate the new expressions to the existing "using" list.
1921                Otherwise, this resets the expression.
1922            dialect: the dialect used to parse the input expressions.
1923            copy: if `False`, modify this expression instance in-place.
1924            opts: other options to use to parse the input expressions.
1925
1926        Returns:
1927            The modified Join expression.
1928        """
1929        join = _apply_list_builder(
1930            *expressions,
1931            instance=self,
1932            arg="using",
1933            append=append,
1934            dialect=dialect,
1935            copy=copy,
1936            **opts,
1937        )
1938
1939        if join.kind == "CROSS":
1940            join.set("kind", None)
1941
1942        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 Expression 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 = 'join'
class Lateral(UDTF):
1945class Lateral(UDTF):
1946    arg_types = {
1947        "this": True,
1948        "view": False,
1949        "outer": False,
1950        "alias": False,
1951        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1952    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
1955class MatchRecognize(Expression):
1956    arg_types = {
1957        "partition_by": False,
1958        "order": False,
1959        "measures": False,
1960        "rows": False,
1961        "after": False,
1962        "pattern": False,
1963        "define": False,
1964        "alias": False,
1965    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1970class Final(Expression):
1971    pass
key = 'final'
class Offset(Expression):
1974class Offset(Expression):
1975    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1978class Order(Expression):
1979    arg_types = {
1980        "this": False,
1981        "expressions": True,
1982        "interpolate": False,
1983        "siblings": False,
1984    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
1988class WithFill(Expression):
1989    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
1994class Cluster(Order):
1995    pass
key = 'cluster'
class Distribute(Order):
1998class Distribute(Order):
1999    pass
key = 'distribute'
class Sort(Order):
2002class Sort(Order):
2003    pass
key = 'sort'
class Ordered(Expression):
2006class Ordered(Expression):
2007    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2010class Property(Expression):
2011    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2014class AlgorithmProperty(Property):
2015    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2018class AutoIncrementProperty(Property):
2019    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2023class AutoRefreshProperty(Property):
2024    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2027class BlockCompressionProperty(Property):
2028    arg_types = {
2029        "autotemp": False,
2030        "always": False,
2031        "default": False,
2032        "manual": False,
2033        "never": False,
2034    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2037class CharacterSetProperty(Property):
2038    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2041class ChecksumProperty(Property):
2042    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2045class CollateProperty(Property):
2046    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2049class CopyGrantsProperty(Property):
2050    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2053class DataBlocksizeProperty(Property):
2054    arg_types = {
2055        "size": False,
2056        "units": False,
2057        "minimum": False,
2058        "maximum": False,
2059        "default": False,
2060    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2063class DefinerProperty(Property):
2064    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2067class DistKeyProperty(Property):
2068    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2071class DistStyleProperty(Property):
2072    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2075class EngineProperty(Property):
2076    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2079class HeapProperty(Property):
2080    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2083class ToTableProperty(Property):
2084    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2087class ExecuteAsProperty(Property):
2088    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2091class ExternalProperty(Property):
2092    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2095class FallbackProperty(Property):
2096    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2099class FileFormatProperty(Property):
2100    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2103class FreespaceProperty(Property):
2104    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InheritsProperty(Property):
2107class InheritsProperty(Property):
2108    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2111class InputModelProperty(Property):
2112    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2115class OutputModelProperty(Property):
2116    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2119class IsolatedLoadingProperty(Property):
2120    arg_types = {
2121        "no": False,
2122        "concurrent": False,
2123        "for_all": False,
2124        "for_insert": False,
2125        "for_none": False,
2126    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2129class JournalProperty(Property):
2130    arg_types = {
2131        "no": False,
2132        "dual": False,
2133        "before": False,
2134        "local": False,
2135        "after": False,
2136    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2139class LanguageProperty(Property):
2140    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2144class ClusteredByProperty(Property):
2145    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2148class DictProperty(Property):
2149    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2152class DictSubProperty(Property):
2153    pass
key = 'dictsubproperty'
class DictRange(Property):
2156class DictRange(Property):
2157    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2162class OnCluster(Property):
2163    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2166class LikeProperty(Property):
2167    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2170class LocationProperty(Property):
2171    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2174class LockingProperty(Property):
2175    arg_types = {
2176        "this": False,
2177        "kind": True,
2178        "for_or_in": False,
2179        "lock_type": True,
2180        "override": False,
2181    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2184class LogProperty(Property):
2185    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2188class MaterializedProperty(Property):
2189    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2192class MergeBlockRatioProperty(Property):
2193    arg_types = {"this": False, "no": False, "default": False, "percent": False}
arg_types = {'this': False, 'no': False, 'default': False, 'percent': False}
key = 'mergeblockratioproperty'
class NoPrimaryIndexProperty(Property):
2196class NoPrimaryIndexProperty(Property):
2197    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2200class OnProperty(Property):
2201    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2204class OnCommitProperty(Property):
2205    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2208class PartitionedByProperty(Property):
2209    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2213class PartitionBoundSpec(Expression):
2214    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2215    arg_types = {
2216        "this": False,
2217        "expression": False,
2218        "from_expressions": False,
2219        "to_expressions": False,
2220    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2223class PartitionedOfProperty(Property):
2224    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2225    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2228class RemoteWithConnectionModelProperty(Property):
2229    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2232class ReturnsProperty(Property):
2233    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2236class RowFormatProperty(Property):
2237    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2240class RowFormatDelimitedProperty(Property):
2241    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2242    arg_types = {
2243        "fields": False,
2244        "escaped": False,
2245        "collection_items": False,
2246        "map_keys": False,
2247        "lines": False,
2248        "null": False,
2249        "serde": False,
2250    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2253class RowFormatSerdeProperty(Property):
2254    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2258class QueryTransform(Expression):
2259    arg_types = {
2260        "expressions": True,
2261        "command_script": True,
2262        "schema": False,
2263        "row_format_before": False,
2264        "record_writer": False,
2265        "row_format_after": False,
2266        "record_reader": False,
2267    }
arg_types = {'expressions': True, 'command_script': True, 'schema': False, 'row_format_before': False, 'record_writer': False, 'row_format_after': False, 'record_reader': False}
key = 'querytransform'
class SampleProperty(Property):
2270class SampleProperty(Property):
2271    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2274class SchemaCommentProperty(Property):
2275    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2278class SerdeProperties(Property):
2279    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2282class SetProperty(Property):
2283    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SetConfigProperty(Property):
2286class SetConfigProperty(Property):
2287    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2290class SettingsProperty(Property):
2291    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2294class SortKeyProperty(Property):
2295    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2298class SqlReadWriteProperty(Property):
2299    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2302class SqlSecurityProperty(Property):
2303    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2306class StabilityProperty(Property):
2307    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2310class TemporaryProperty(Property):
2311    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2314class TransformModelProperty(Property):
2315    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2318class TransientProperty(Property):
2319    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2322class VolatileProperty(Property):
2323    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2326class WithDataProperty(Property):
2327    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2330class WithJournalTableProperty(Property):
2331    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2334class WithSystemVersioningProperty(Property):
2335    # this -> history table name, expression -> data consistency check
2336    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2339class Properties(Expression):
2340    arg_types = {"expressions": True}
2341
2342    NAME_TO_PROPERTY = {
2343        "ALGORITHM": AlgorithmProperty,
2344        "AUTO_INCREMENT": AutoIncrementProperty,
2345        "CHARACTER SET": CharacterSetProperty,
2346        "CLUSTERED_BY": ClusteredByProperty,
2347        "COLLATE": CollateProperty,
2348        "COMMENT": SchemaCommentProperty,
2349        "DEFINER": DefinerProperty,
2350        "DISTKEY": DistKeyProperty,
2351        "DISTSTYLE": DistStyleProperty,
2352        "ENGINE": EngineProperty,
2353        "EXECUTE AS": ExecuteAsProperty,
2354        "FORMAT": FileFormatProperty,
2355        "LANGUAGE": LanguageProperty,
2356        "LOCATION": LocationProperty,
2357        "PARTITIONED_BY": PartitionedByProperty,
2358        "RETURNS": ReturnsProperty,
2359        "ROW_FORMAT": RowFormatProperty,
2360        "SORTKEY": SortKeyProperty,
2361    }
2362
2363    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2364
2365    # CREATE property locations
2366    # Form: schema specified
2367    #   create [POST_CREATE]
2368    #     table a [POST_NAME]
2369    #     (b int) [POST_SCHEMA]
2370    #     with ([POST_WITH])
2371    #     index (b) [POST_INDEX]
2372    #
2373    # Form: alias selection
2374    #   create [POST_CREATE]
2375    #     table a [POST_NAME]
2376    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2377    #     index (c) [POST_INDEX]
2378    class Location(AutoName):
2379        POST_CREATE = auto()
2380        POST_NAME = auto()
2381        POST_SCHEMA = auto()
2382        POST_WITH = auto()
2383        POST_ALIAS = auto()
2384        POST_EXPRESSION = auto()
2385        POST_INDEX = auto()
2386        UNSUPPORTED = auto()
2387
2388    @classmethod
2389    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2390        expressions = []
2391        for key, value in properties_dict.items():
2392            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2393            if property_cls:
2394                expressions.append(property_cls(this=convert(value)))
2395            else:
2396                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2397
2398        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2388    @classmethod
2389    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2390        expressions = []
2391        for key, value in properties_dict.items():
2392            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2393            if property_cls:
2394                expressions.append(property_cls(this=convert(value)))
2395            else:
2396                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2397
2398        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2378    class Location(AutoName):
2379        POST_CREATE = auto()
2380        POST_NAME = auto()
2381        POST_SCHEMA = auto()
2382        POST_WITH = auto()
2383        POST_ALIAS = auto()
2384        POST_EXPRESSION = auto()
2385        POST_INDEX = auto()
2386        UNSUPPORTED = auto()

An enumeration.

POST_CREATE = <Location.POST_CREATE: 'POST_CREATE'>
POST_NAME = <Location.POST_NAME: 'POST_NAME'>
POST_SCHEMA = <Location.POST_SCHEMA: 'POST_SCHEMA'>
POST_WITH = <Location.POST_WITH: 'POST_WITH'>
POST_ALIAS = <Location.POST_ALIAS: 'POST_ALIAS'>
POST_EXPRESSION = <Location.POST_EXPRESSION: 'POST_EXPRESSION'>
POST_INDEX = <Location.POST_INDEX: 'POST_INDEX'>
UNSUPPORTED = <Location.UNSUPPORTED: 'UNSUPPORTED'>
Inherited Members
enum.Enum
name
value
class Qualify(Expression):
2401class Qualify(Expression):
2402    pass
key = 'qualify'
class InputOutputFormat(Expression):
2405class InputOutputFormat(Expression):
2406    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2410class Return(Expression):
2411    pass
key = 'return'
class Reference(Expression):
2414class Reference(Expression):
2415    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2418class Tuple(Expression):
2419    arg_types = {"expressions": False}
2420
2421    def isin(
2422        self,
2423        *expressions: t.Any,
2424        query: t.Optional[ExpOrStr] = None,
2425        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2426        copy: bool = True,
2427        **opts,
2428    ) -> In:
2429        return In(
2430            this=maybe_copy(self, copy),
2431            expressions=[convert(e, copy=copy) for e in expressions],
2432            query=maybe_parse(query, copy=copy, **opts) if query else None,
2433            unnest=(
2434                Unnest(
2435                    expressions=[
2436                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2437                        for e in ensure_list(unnest)
2438                    ]
2439                )
2440                if unnest
2441                else None
2442            ),
2443        )
arg_types = {'expressions': False}
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
2421    def isin(
2422        self,
2423        *expressions: t.Any,
2424        query: t.Optional[ExpOrStr] = None,
2425        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2426        copy: bool = True,
2427        **opts,
2428    ) -> In:
2429        return In(
2430            this=maybe_copy(self, copy),
2431            expressions=[convert(e, copy=copy) for e in expressions],
2432            query=maybe_parse(query, copy=copy, **opts) if query else None,
2433            unnest=(
2434                Unnest(
2435                    expressions=[
2436                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2437                        for e in ensure_list(unnest)
2438                    ]
2439                )
2440                if unnest
2441                else None
2442            ),
2443        )
key = 'tuple'
class Subqueryable(Unionable):
2446class Subqueryable(Unionable):
2447    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2448        """
2449        Convert this expression to an aliased expression that can be used as a Subquery.
2450
2451        Example:
2452            >>> subquery = Select().select("x").from_("tbl").subquery()
2453            >>> Select().select("x").from_(subquery).sql()
2454            'SELECT x FROM (SELECT x FROM tbl)'
2455
2456        Args:
2457            alias (str | Identifier): an optional alias for the subquery
2458            copy (bool): if `False`, modify this expression instance in-place.
2459
2460        Returns:
2461            Alias: the subquery
2462        """
2463        instance = maybe_copy(self, copy)
2464        if not isinstance(alias, Expression):
2465            alias = TableAlias(this=to_identifier(alias)) if alias else None
2466
2467        return Subquery(this=instance, alias=alias)
2468
2469    def limit(
2470        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2471    ) -> Select:
2472        raise NotImplementedError
2473
2474    @property
2475    def ctes(self):
2476        with_ = self.args.get("with")
2477        if not with_:
2478            return []
2479        return with_.expressions
2480
2481    @property
2482    def selects(self) -> t.List[Expression]:
2483        raise NotImplementedError("Subqueryable objects must implement `selects`")
2484
2485    @property
2486    def named_selects(self) -> t.List[str]:
2487        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2488
2489    def select(
2490        self,
2491        *expressions: t.Optional[ExpOrStr],
2492        append: bool = True,
2493        dialect: DialectType = None,
2494        copy: bool = True,
2495        **opts,
2496    ) -> Subqueryable:
2497        raise NotImplementedError("Subqueryable objects must implement `select`")
2498
2499    def with_(
2500        self,
2501        alias: ExpOrStr,
2502        as_: ExpOrStr,
2503        recursive: t.Optional[bool] = None,
2504        append: bool = True,
2505        dialect: DialectType = None,
2506        copy: bool = True,
2507        **opts,
2508    ) -> Subqueryable:
2509        """
2510        Append to or set the common table expressions.
2511
2512        Example:
2513            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2514            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2515
2516        Args:
2517            alias: the SQL code string to parse as the table name.
2518                If an `Expression` instance is passed, this is used as-is.
2519            as_: the SQL code string to parse as the table expression.
2520                If an `Expression` instance is passed, it will be used as-is.
2521            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2522            append: if `True`, add to any existing expressions.
2523                Otherwise, this resets the expressions.
2524            dialect: the dialect used to parse the input expression.
2525            copy: if `False`, modify this expression instance in-place.
2526            opts: other options to use to parse the input expressions.
2527
2528        Returns:
2529            The modified expression.
2530        """
2531        return _apply_cte_builder(
2532            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2533        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2447    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2448        """
2449        Convert this expression to an aliased expression that can be used as a Subquery.
2450
2451        Example:
2452            >>> subquery = Select().select("x").from_("tbl").subquery()
2453            >>> Select().select("x").from_(subquery).sql()
2454            'SELECT x FROM (SELECT x FROM tbl)'
2455
2456        Args:
2457            alias (str | Identifier): an optional alias for the subquery
2458            copy (bool): if `False`, modify this expression instance in-place.
2459
2460        Returns:
2461            Alias: the subquery
2462        """
2463        instance = maybe_copy(self, copy)
2464        if not isinstance(alias, Expression):
2465            alias = TableAlias(this=to_identifier(alias)) if alias else None
2466
2467        return Subquery(this=instance, alias=alias)

Convert this expression to an aliased expression that can be used as a Subquery.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias (str | Identifier): an optional alias for the subquery
  • copy (bool): if False, modify this expression instance in-place.
Returns:

Alias: the subquery

def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2469    def limit(
2470        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2471    ) -> Select:
2472        raise NotImplementedError
ctes
2474    @property
2475    def ctes(self):
2476        with_ = self.args.get("with")
2477        if not with_:
2478            return []
2479        return with_.expressions
selects: List[Expression]
2481    @property
2482    def selects(self) -> t.List[Expression]:
2483        raise NotImplementedError("Subqueryable objects must implement `selects`")
named_selects: List[str]
2485    @property
2486    def named_selects(self) -> t.List[str]:
2487        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subqueryable:
2489    def select(
2490        self,
2491        *expressions: t.Optional[ExpOrStr],
2492        append: bool = True,
2493        dialect: DialectType = None,
2494        copy: bool = True,
2495        **opts,
2496    ) -> Subqueryable:
2497        raise NotImplementedError("Subqueryable objects must implement `select`")
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subqueryable:
2499    def with_(
2500        self,
2501        alias: ExpOrStr,
2502        as_: ExpOrStr,
2503        recursive: t.Optional[bool] = None,
2504        append: bool = True,
2505        dialect: DialectType = None,
2506        copy: bool = True,
2507        **opts,
2508    ) -> Subqueryable:
2509        """
2510        Append to or set the common table expressions.
2511
2512        Example:
2513            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2514            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2515
2516        Args:
2517            alias: the SQL code string to parse as the table name.
2518                If an `Expression` instance is passed, this is used as-is.
2519            as_: the SQL code string to parse as the table expression.
2520                If an `Expression` instance is passed, it will be used as-is.
2521            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2522            append: if `True`, add to any existing expressions.
2523                Otherwise, this resets the expressions.
2524            dialect: the dialect used to parse the input expression.
2525            copy: if `False`, modify this expression instance in-place.
2526            opts: other options to use to parse the input expressions.
2527
2528        Returns:
2529            The modified expression.
2530        """
2531        return _apply_cte_builder(
2532            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2533        )

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 Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • 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.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

key = 'subqueryable'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
class WithTableHint(Expression):
2561class WithTableHint(Expression):
2562    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2566class IndexTableHint(Expression):
2567    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2571class HistoricalData(Expression):
2572    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2575class Table(Expression):
2576    arg_types = {
2577        "this": True,
2578        "alias": False,
2579        "db": False,
2580        "catalog": False,
2581        "laterals": False,
2582        "joins": False,
2583        "pivots": False,
2584        "hints": False,
2585        "system_time": False,
2586        "version": False,
2587        "format": False,
2588        "pattern": False,
2589        "ordinality": False,
2590        "when": False,
2591    }
2592
2593    @property
2594    def name(self) -> str:
2595        if isinstance(self.this, Func):
2596            return ""
2597        return self.this.name
2598
2599    @property
2600    def db(self) -> str:
2601        return self.text("db")
2602
2603    @property
2604    def catalog(self) -> str:
2605        return self.text("catalog")
2606
2607    @property
2608    def selects(self) -> t.List[Expression]:
2609        return []
2610
2611    @property
2612    def named_selects(self) -> t.List[str]:
2613        return []
2614
2615    @property
2616    def parts(self) -> t.List[Expression]:
2617        """Return the parts of a table in order catalog, db, table."""
2618        parts: t.List[Expression] = []
2619
2620        for arg in ("catalog", "db", "this"):
2621            part = self.args.get(arg)
2622
2623            if isinstance(part, Dot):
2624                parts.extend(part.flatten())
2625            elif isinstance(part, Expression):
2626                parts.append(part)
2627
2628        return parts
2629
2630    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2631        parts = self.parts
2632        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2633        alias = self.args.get("alias")
2634        if alias:
2635            col = alias_(col, alias.this, copy=copy)
2636        return col
arg_types = {'this': True, '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}
name: str
2593    @property
2594    def name(self) -> str:
2595        if isinstance(self.this, Func):
2596            return ""
2597        return self.this.name
db: str
2599    @property
2600    def db(self) -> str:
2601        return self.text("db")
catalog: str
2603    @property
2604    def catalog(self) -> str:
2605        return self.text("catalog")
selects: List[Expression]
2607    @property
2608    def selects(self) -> t.List[Expression]:
2609        return []
named_selects: List[str]
2611    @property
2612    def named_selects(self) -> t.List[str]:
2613        return []
parts: List[Expression]
2615    @property
2616    def parts(self) -> t.List[Expression]:
2617        """Return the parts of a table in order catalog, db, table."""
2618        parts: t.List[Expression] = []
2619
2620        for arg in ("catalog", "db", "this"):
2621            part = self.args.get(arg)
2622
2623            if isinstance(part, Dot):
2624                parts.extend(part.flatten())
2625            elif isinstance(part, Expression):
2626                parts.append(part)
2627
2628        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2630    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2631        parts = self.parts
2632        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2633        alias = self.args.get("alias")
2634        if alias:
2635            col = alias_(col, alias.this, copy=copy)
2636        return col
key = 'table'
class Union(Subqueryable):
2639class Union(Subqueryable):
2640    arg_types = {
2641        "with": False,
2642        "this": True,
2643        "expression": True,
2644        "distinct": False,
2645        "by_name": False,
2646        **QUERY_MODIFIERS,
2647    }
2648
2649    def limit(
2650        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2651    ) -> Select:
2652        """
2653        Set the LIMIT expression.
2654
2655        Example:
2656            >>> select("1").union(select("1")).limit(1).sql()
2657            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2658
2659        Args:
2660            expression: the SQL code string to parse.
2661                This can also be an integer.
2662                If a `Limit` instance is passed, this is used as-is.
2663                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2664            dialect: the dialect used to parse the input expression.
2665            copy: if `False`, modify this expression instance in-place.
2666            opts: other options to use to parse the input expressions.
2667
2668        Returns:
2669            The limited subqueryable.
2670        """
2671        return (
2672            select("*")
2673            .from_(self.subquery(alias="_l_0", copy=copy))
2674            .limit(expression, dialect=dialect, copy=False, **opts)
2675        )
2676
2677    def select(
2678        self,
2679        *expressions: t.Optional[ExpOrStr],
2680        append: bool = True,
2681        dialect: DialectType = None,
2682        copy: bool = True,
2683        **opts,
2684    ) -> Union:
2685        """Append to or set the SELECT of the union recursively.
2686
2687        Example:
2688            >>> from sqlglot import parse_one
2689            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2690            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2691
2692        Args:
2693            *expressions: the SQL code strings to parse.
2694                If an `Expression` instance is passed, it will be used as-is.
2695            append: if `True`, add to any existing expressions.
2696                Otherwise, this resets the expressions.
2697            dialect: the dialect used to parse the input expressions.
2698            copy: if `False`, modify this expression instance in-place.
2699            opts: other options to use to parse the input expressions.
2700
2701        Returns:
2702            Union: the modified expression.
2703        """
2704        this = self.copy() if copy else self
2705        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2706        this.expression.unnest().select(
2707            *expressions, append=append, dialect=dialect, copy=False, **opts
2708        )
2709        return this
2710
2711    @property
2712    def named_selects(self) -> t.List[str]:
2713        return self.this.unnest().named_selects
2714
2715    @property
2716    def is_star(self) -> bool:
2717        return self.this.is_star or self.expression.is_star
2718
2719    @property
2720    def selects(self) -> t.List[Expression]:
2721        return self.this.unnest().selects
2722
2723    @property
2724    def left(self) -> Expression:
2725        return self.this
2726
2727    @property
2728    def right(self) -> Expression:
2729        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2649    def limit(
2650        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2651    ) -> Select:
2652        """
2653        Set the LIMIT expression.
2654
2655        Example:
2656            >>> select("1").union(select("1")).limit(1).sql()
2657            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2658
2659        Args:
2660            expression: the SQL code string to parse.
2661                This can also be an integer.
2662                If a `Limit` instance is passed, this is used as-is.
2663                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2664            dialect: the dialect used to parse the input expression.
2665            copy: if `False`, modify this expression instance in-place.
2666            opts: other options to use to parse the input expressions.
2667
2668        Returns:
2669            The limited subqueryable.
2670        """
2671        return (
2672            select("*")
2673            .from_(self.subquery(alias="_l_0", copy=copy))
2674            .limit(expression, dialect=dialect, copy=False, **opts)
2675        )

Set the LIMIT expression.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, this is used as-is. If another Expression 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:

The limited subqueryable.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
2677    def select(
2678        self,
2679        *expressions: t.Optional[ExpOrStr],
2680        append: bool = True,
2681        dialect: DialectType = None,
2682        copy: bool = True,
2683        **opts,
2684    ) -> Union:
2685        """Append to or set the SELECT of the union recursively.
2686
2687        Example:
2688            >>> from sqlglot import parse_one
2689            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2690            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2691
2692        Args:
2693            *expressions: the SQL code strings to parse.
2694                If an `Expression` instance is passed, it will be used as-is.
2695            append: if `True`, add to any existing expressions.
2696                Otherwise, this resets the expressions.
2697            dialect: the dialect used to parse the input expressions.
2698            copy: if `False`, modify this expression instance in-place.
2699            opts: other options to use to parse the input expressions.
2700
2701        Returns:
2702            Union: the modified expression.
2703        """
2704        this = self.copy() if copy else self
2705        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2706        this.expression.unnest().select(
2707            *expressions, append=append, dialect=dialect, copy=False, **opts
2708        )
2709        return this

Append to or set the SELECT of the union recursively.

Example:
>>> from sqlglot import parse_one
>>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression 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:

Union: the modified expression.

named_selects: List[str]
2711    @property
2712    def named_selects(self) -> t.List[str]:
2713        return self.this.unnest().named_selects
is_star: bool
2715    @property
2716    def is_star(self) -> bool:
2717        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2719    @property
2720    def selects(self) -> t.List[Expression]:
2721        return self.this.unnest().selects
left: Expression
2723    @property
2724    def left(self) -> Expression:
2725        return self.this
right: Expression
2727    @property
2728    def right(self) -> Expression:
2729        return self.expression
key = 'union'
class Except(Union):
2732class Except(Union):
2733    pass
key = 'except'
class Intersect(Union):
2736class Intersect(Union):
2737    pass
key = 'intersect'
class Unnest(UDTF):
2740class Unnest(UDTF):
2741    arg_types = {
2742        "expressions": True,
2743        "alias": False,
2744        "offset": False,
2745    }
2746
2747    @property
2748    def selects(self) -> t.List[Expression]:
2749        columns = super().selects
2750        offset = self.args.get("offset")
2751        if offset:
2752            columns = columns + [to_identifier("offset") if offset is True else offset]
2753        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
2747    @property
2748    def selects(self) -> t.List[Expression]:
2749        columns = super().selects
2750        offset = self.args.get("offset")
2751        if offset:
2752            columns = columns + [to_identifier("offset") if offset is True else offset]
2753        return columns
key = 'unnest'
class Update(Expression):
2756class Update(Expression):
2757    arg_types = {
2758        "with": False,
2759        "this": False,
2760        "expressions": True,
2761        "from": False,
2762        "where": False,
2763        "returning": False,
2764        "order": False,
2765        "limit": False,
2766    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
2769class Values(UDTF):
2770    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
2773class Var(Expression):
2774    pass
key = 'var'
class Version(Expression):
2777class Version(Expression):
2778    """
2779    Time travel, iceberg, bigquery etc
2780    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2781    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2782    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2783    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2784    this is either TIMESTAMP or VERSION
2785    kind is ("AS OF", "BETWEEN")
2786    """
2787
2788    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
2791class Schema(Expression):
2792    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
2797class Lock(Expression):
2798    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Subqueryable):
2801class Select(Subqueryable):
2802    arg_types = {
2803        "with": False,
2804        "kind": False,
2805        "expressions": False,
2806        "hint": False,
2807        "distinct": False,
2808        "into": False,
2809        "from": False,
2810        **QUERY_MODIFIERS,
2811    }
2812
2813    def from_(
2814        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2815    ) -> Select:
2816        """
2817        Set the FROM expression.
2818
2819        Example:
2820            >>> Select().from_("tbl").select("x").sql()
2821            'SELECT x FROM tbl'
2822
2823        Args:
2824            expression : the SQL code strings to parse.
2825                If a `From` instance is passed, this is used as-is.
2826                If another `Expression` instance is passed, it will be wrapped in a `From`.
2827            dialect: the dialect used to parse the input expression.
2828            copy: if `False`, modify this expression instance in-place.
2829            opts: other options to use to parse the input expressions.
2830
2831        Returns:
2832            The modified Select expression.
2833        """
2834        return _apply_builder(
2835            expression=expression,
2836            instance=self,
2837            arg="from",
2838            into=From,
2839            prefix="FROM",
2840            dialect=dialect,
2841            copy=copy,
2842            **opts,
2843        )
2844
2845    def group_by(
2846        self,
2847        *expressions: t.Optional[ExpOrStr],
2848        append: bool = True,
2849        dialect: DialectType = None,
2850        copy: bool = True,
2851        **opts,
2852    ) -> Select:
2853        """
2854        Set the GROUP BY expression.
2855
2856        Example:
2857            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2858            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2859
2860        Args:
2861            *expressions: the SQL code strings to parse.
2862                If a `Group` instance is passed, this is used as-is.
2863                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2864                If nothing is passed in then a group by is not applied to the expression
2865            append: if `True`, add to any existing expressions.
2866                Otherwise, this flattens all the `Group` expression into a single expression.
2867            dialect: the dialect used to parse the input expression.
2868            copy: if `False`, modify this expression instance in-place.
2869            opts: other options to use to parse the input expressions.
2870
2871        Returns:
2872            The modified Select expression.
2873        """
2874        if not expressions:
2875            return self if not copy else self.copy()
2876
2877        return _apply_child_list_builder(
2878            *expressions,
2879            instance=self,
2880            arg="group",
2881            append=append,
2882            copy=copy,
2883            prefix="GROUP BY",
2884            into=Group,
2885            dialect=dialect,
2886            **opts,
2887        )
2888
2889    def order_by(
2890        self,
2891        *expressions: t.Optional[ExpOrStr],
2892        append: bool = True,
2893        dialect: DialectType = None,
2894        copy: bool = True,
2895        **opts,
2896    ) -> Select:
2897        """
2898        Set the ORDER BY expression.
2899
2900        Example:
2901            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2902            'SELECT x FROM tbl ORDER BY x DESC'
2903
2904        Args:
2905            *expressions: the SQL code strings to parse.
2906                If a `Group` instance is passed, this is used as-is.
2907                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2908            append: if `True`, add to any existing expressions.
2909                Otherwise, this flattens all the `Order` expression into a single expression.
2910            dialect: the dialect used to parse the input expression.
2911            copy: if `False`, modify this expression instance in-place.
2912            opts: other options to use to parse the input expressions.
2913
2914        Returns:
2915            The modified Select expression.
2916        """
2917        return _apply_child_list_builder(
2918            *expressions,
2919            instance=self,
2920            arg="order",
2921            append=append,
2922            copy=copy,
2923            prefix="ORDER BY",
2924            into=Order,
2925            dialect=dialect,
2926            **opts,
2927        )
2928
2929    def sort_by(
2930        self,
2931        *expressions: t.Optional[ExpOrStr],
2932        append: bool = True,
2933        dialect: DialectType = None,
2934        copy: bool = True,
2935        **opts,
2936    ) -> Select:
2937        """
2938        Set the SORT BY expression.
2939
2940        Example:
2941            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2942            'SELECT x FROM tbl SORT BY x DESC'
2943
2944        Args:
2945            *expressions: the SQL code strings to parse.
2946                If a `Group` instance is passed, this is used as-is.
2947                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2948            append: if `True`, add to any existing expressions.
2949                Otherwise, this flattens all the `Order` expression into a single expression.
2950            dialect: the dialect used to parse the input expression.
2951            copy: if `False`, modify this expression instance in-place.
2952            opts: other options to use to parse the input expressions.
2953
2954        Returns:
2955            The modified Select expression.
2956        """
2957        return _apply_child_list_builder(
2958            *expressions,
2959            instance=self,
2960            arg="sort",
2961            append=append,
2962            copy=copy,
2963            prefix="SORT BY",
2964            into=Sort,
2965            dialect=dialect,
2966            **opts,
2967        )
2968
2969    def cluster_by(
2970        self,
2971        *expressions: t.Optional[ExpOrStr],
2972        append: bool = True,
2973        dialect: DialectType = None,
2974        copy: bool = True,
2975        **opts,
2976    ) -> Select:
2977        """
2978        Set the CLUSTER BY expression.
2979
2980        Example:
2981            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2982            'SELECT x FROM tbl CLUSTER BY x DESC'
2983
2984        Args:
2985            *expressions: the SQL code strings to parse.
2986                If a `Group` instance is passed, this is used as-is.
2987                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2988            append: if `True`, add to any existing expressions.
2989                Otherwise, this flattens all the `Order` expression into a single expression.
2990            dialect: the dialect used to parse the input expression.
2991            copy: if `False`, modify this expression instance in-place.
2992            opts: other options to use to parse the input expressions.
2993
2994        Returns:
2995            The modified Select expression.
2996        """
2997        return _apply_child_list_builder(
2998            *expressions,
2999            instance=self,
3000            arg="cluster",
3001            append=append,
3002            copy=copy,
3003            prefix="CLUSTER BY",
3004            into=Cluster,
3005            dialect=dialect,
3006            **opts,
3007        )
3008
3009    def limit(
3010        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3011    ) -> Select:
3012        """
3013        Set the LIMIT expression.
3014
3015        Example:
3016            >>> Select().from_("tbl").select("x").limit(10).sql()
3017            'SELECT x FROM tbl LIMIT 10'
3018
3019        Args:
3020            expression: the SQL code string to parse.
3021                This can also be an integer.
3022                If a `Limit` instance is passed, this is used as-is.
3023                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
3024            dialect: the dialect used to parse the input expression.
3025            copy: if `False`, modify this expression instance in-place.
3026            opts: other options to use to parse the input expressions.
3027
3028        Returns:
3029            Select: the modified expression.
3030        """
3031        return _apply_builder(
3032            expression=expression,
3033            instance=self,
3034            arg="limit",
3035            into=Limit,
3036            prefix="LIMIT",
3037            dialect=dialect,
3038            copy=copy,
3039            into_arg="expression",
3040            **opts,
3041        )
3042
3043    def offset(
3044        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3045    ) -> Select:
3046        """
3047        Set the OFFSET expression.
3048
3049        Example:
3050            >>> Select().from_("tbl").select("x").offset(10).sql()
3051            'SELECT x FROM tbl OFFSET 10'
3052
3053        Args:
3054            expression: the SQL code string to parse.
3055                This can also be an integer.
3056                If a `Offset` instance is passed, this is used as-is.
3057                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3058            dialect: the dialect used to parse the input expression.
3059            copy: if `False`, modify this expression instance in-place.
3060            opts: other options to use to parse the input expressions.
3061
3062        Returns:
3063            The modified Select expression.
3064        """
3065        return _apply_builder(
3066            expression=expression,
3067            instance=self,
3068            arg="offset",
3069            into=Offset,
3070            prefix="OFFSET",
3071            dialect=dialect,
3072            copy=copy,
3073            into_arg="expression",
3074            **opts,
3075        )
3076
3077    def select(
3078        self,
3079        *expressions: t.Optional[ExpOrStr],
3080        append: bool = True,
3081        dialect: DialectType = None,
3082        copy: bool = True,
3083        **opts,
3084    ) -> Select:
3085        """
3086        Append to or set the SELECT expressions.
3087
3088        Example:
3089            >>> Select().select("x", "y").sql()
3090            'SELECT x, y'
3091
3092        Args:
3093            *expressions: the SQL code strings to parse.
3094                If an `Expression` instance is passed, it will be used as-is.
3095            append: if `True`, add to any existing expressions.
3096                Otherwise, this resets the expressions.
3097            dialect: the dialect used to parse the input expressions.
3098            copy: if `False`, modify this expression instance in-place.
3099            opts: other options to use to parse the input expressions.
3100
3101        Returns:
3102            The modified Select expression.
3103        """
3104        return _apply_list_builder(
3105            *expressions,
3106            instance=self,
3107            arg="expressions",
3108            append=append,
3109            dialect=dialect,
3110            copy=copy,
3111            **opts,
3112        )
3113
3114    def lateral(
3115        self,
3116        *expressions: t.Optional[ExpOrStr],
3117        append: bool = True,
3118        dialect: DialectType = None,
3119        copy: bool = True,
3120        **opts,
3121    ) -> Select:
3122        """
3123        Append to or set the LATERAL expressions.
3124
3125        Example:
3126            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3127            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3128
3129        Args:
3130            *expressions: the SQL code strings to parse.
3131                If an `Expression` instance is passed, it will be used as-is.
3132            append: if `True`, add to any existing expressions.
3133                Otherwise, this resets the expressions.
3134            dialect: the dialect used to parse the input expressions.
3135            copy: if `False`, modify this expression instance in-place.
3136            opts: other options to use to parse the input expressions.
3137
3138        Returns:
3139            The modified Select expression.
3140        """
3141        return _apply_list_builder(
3142            *expressions,
3143            instance=self,
3144            arg="laterals",
3145            append=append,
3146            into=Lateral,
3147            prefix="LATERAL VIEW",
3148            dialect=dialect,
3149            copy=copy,
3150            **opts,
3151        )
3152
3153    def join(
3154        self,
3155        expression: ExpOrStr,
3156        on: t.Optional[ExpOrStr] = None,
3157        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3158        append: bool = True,
3159        join_type: t.Optional[str] = None,
3160        join_alias: t.Optional[Identifier | str] = None,
3161        dialect: DialectType = None,
3162        copy: bool = True,
3163        **opts,
3164    ) -> Select:
3165        """
3166        Append to or set the JOIN expressions.
3167
3168        Example:
3169            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3170            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3171
3172            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3173            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3174
3175            Use `join_type` to change the type of join:
3176
3177            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3178            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3179
3180        Args:
3181            expression: the SQL code string to parse.
3182                If an `Expression` instance is passed, it will be used as-is.
3183            on: optionally specify the join "on" criteria as a SQL string.
3184                If an `Expression` instance is passed, it will be used as-is.
3185            using: optionally specify the join "using" criteria as a SQL string.
3186                If an `Expression` instance is passed, it will be used as-is.
3187            append: if `True`, add to any existing expressions.
3188                Otherwise, this resets the expressions.
3189            join_type: if set, alter the parsed join type.
3190            join_alias: an optional alias for the joined source.
3191            dialect: the dialect used to parse the input expressions.
3192            copy: if `False`, modify this expression instance in-place.
3193            opts: other options to use to parse the input expressions.
3194
3195        Returns:
3196            Select: the modified expression.
3197        """
3198        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3199
3200        try:
3201            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3202        except ParseError:
3203            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3204
3205        join = expression if isinstance(expression, Join) else Join(this=expression)
3206
3207        if isinstance(join.this, Select):
3208            join.this.replace(join.this.subquery())
3209
3210        if join_type:
3211            method: t.Optional[Token]
3212            side: t.Optional[Token]
3213            kind: t.Optional[Token]
3214
3215            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3216
3217            if method:
3218                join.set("method", method.text)
3219            if side:
3220                join.set("side", side.text)
3221            if kind:
3222                join.set("kind", kind.text)
3223
3224        if on:
3225            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3226            join.set("on", on)
3227
3228        if using:
3229            join = _apply_list_builder(
3230                *ensure_list(using),
3231                instance=join,
3232                arg="using",
3233                append=append,
3234                copy=copy,
3235                into=Identifier,
3236                **opts,
3237            )
3238
3239        if join_alias:
3240            join.set("this", alias_(join.this, join_alias, table=True))
3241
3242        return _apply_list_builder(
3243            join,
3244            instance=self,
3245            arg="joins",
3246            append=append,
3247            copy=copy,
3248            **opts,
3249        )
3250
3251    def where(
3252        self,
3253        *expressions: t.Optional[ExpOrStr],
3254        append: bool = True,
3255        dialect: DialectType = None,
3256        copy: bool = True,
3257        **opts,
3258    ) -> Select:
3259        """
3260        Append to or set the WHERE expressions.
3261
3262        Example:
3263            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3264            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3265
3266        Args:
3267            *expressions: the SQL code strings to parse.
3268                If an `Expression` instance is passed, it will be used as-is.
3269                Multiple expressions are combined with an AND operator.
3270            append: if `True`, AND the new expressions to any existing expression.
3271                Otherwise, this resets the expression.
3272            dialect: the dialect used to parse the input expressions.
3273            copy: if `False`, modify this expression instance in-place.
3274            opts: other options to use to parse the input expressions.
3275
3276        Returns:
3277            Select: the modified expression.
3278        """
3279        return _apply_conjunction_builder(
3280            *expressions,
3281            instance=self,
3282            arg="where",
3283            append=append,
3284            into=Where,
3285            dialect=dialect,
3286            copy=copy,
3287            **opts,
3288        )
3289
3290    def having(
3291        self,
3292        *expressions: t.Optional[ExpOrStr],
3293        append: bool = True,
3294        dialect: DialectType = None,
3295        copy: bool = True,
3296        **opts,
3297    ) -> Select:
3298        """
3299        Append to or set the HAVING expressions.
3300
3301        Example:
3302            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3303            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3304
3305        Args:
3306            *expressions: the SQL code strings to parse.
3307                If an `Expression` instance is passed, it will be used as-is.
3308                Multiple expressions are combined with an AND operator.
3309            append: if `True`, AND the new expressions to any existing expression.
3310                Otherwise, this resets the expression.
3311            dialect: the dialect used to parse the input expressions.
3312            copy: if `False`, modify this expression instance in-place.
3313            opts: other options to use to parse the input expressions.
3314
3315        Returns:
3316            The modified Select expression.
3317        """
3318        return _apply_conjunction_builder(
3319            *expressions,
3320            instance=self,
3321            arg="having",
3322            append=append,
3323            into=Having,
3324            dialect=dialect,
3325            copy=copy,
3326            **opts,
3327        )
3328
3329    def window(
3330        self,
3331        *expressions: t.Optional[ExpOrStr],
3332        append: bool = True,
3333        dialect: DialectType = None,
3334        copy: bool = True,
3335        **opts,
3336    ) -> Select:
3337        return _apply_list_builder(
3338            *expressions,
3339            instance=self,
3340            arg="windows",
3341            append=append,
3342            into=Window,
3343            dialect=dialect,
3344            copy=copy,
3345            **opts,
3346        )
3347
3348    def qualify(
3349        self,
3350        *expressions: t.Optional[ExpOrStr],
3351        append: bool = True,
3352        dialect: DialectType = None,
3353        copy: bool = True,
3354        **opts,
3355    ) -> Select:
3356        return _apply_conjunction_builder(
3357            *expressions,
3358            instance=self,
3359            arg="qualify",
3360            append=append,
3361            into=Qualify,
3362            dialect=dialect,
3363            copy=copy,
3364            **opts,
3365        )
3366
3367    def distinct(
3368        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3369    ) -> Select:
3370        """
3371        Set the OFFSET expression.
3372
3373        Example:
3374            >>> Select().from_("tbl").select("x").distinct().sql()
3375            'SELECT DISTINCT x FROM tbl'
3376
3377        Args:
3378            ons: the expressions to distinct on
3379            distinct: whether the Select should be distinct
3380            copy: if `False`, modify this expression instance in-place.
3381
3382        Returns:
3383            Select: the modified expression.
3384        """
3385        instance = maybe_copy(self, copy)
3386        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3387        instance.set("distinct", Distinct(on=on) if distinct else None)
3388        return instance
3389
3390    def ctas(
3391        self,
3392        table: ExpOrStr,
3393        properties: t.Optional[t.Dict] = None,
3394        dialect: DialectType = None,
3395        copy: bool = True,
3396        **opts,
3397    ) -> Create:
3398        """
3399        Convert this expression to a CREATE TABLE AS statement.
3400
3401        Example:
3402            >>> Select().select("*").from_("tbl").ctas("x").sql()
3403            'CREATE TABLE x AS SELECT * FROM tbl'
3404
3405        Args:
3406            table: the SQL code string to parse as the table name.
3407                If another `Expression` instance is passed, it will be used as-is.
3408            properties: an optional mapping of table properties
3409            dialect: the dialect used to parse the input table.
3410            copy: if `False`, modify this expression instance in-place.
3411            opts: other options to use to parse the input table.
3412
3413        Returns:
3414            The new Create expression.
3415        """
3416        instance = maybe_copy(self, copy)
3417        table_expression = maybe_parse(
3418            table,
3419            into=Table,
3420            dialect=dialect,
3421            **opts,
3422        )
3423        properties_expression = None
3424        if properties:
3425            properties_expression = Properties.from_dict(properties)
3426
3427        return Create(
3428            this=table_expression,
3429            kind="TABLE",
3430            expression=instance,
3431            properties=properties_expression,
3432        )
3433
3434    def lock(self, update: bool = True, copy: bool = True) -> Select:
3435        """
3436        Set the locking read mode for this expression.
3437
3438        Examples:
3439            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3440            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3441
3442            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3443            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3444
3445        Args:
3446            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3447            copy: if `False`, modify this expression instance in-place.
3448
3449        Returns:
3450            The modified expression.
3451        """
3452        inst = maybe_copy(self, copy)
3453        inst.set("locks", [Lock(update=update)])
3454
3455        return inst
3456
3457    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3458        """
3459        Set hints for this expression.
3460
3461        Examples:
3462            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3463            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3464
3465        Args:
3466            hints: The SQL code strings to parse as the hints.
3467                If an `Expression` instance is passed, it will be used as-is.
3468            dialect: The dialect used to parse the hints.
3469            copy: If `False`, modify this expression instance in-place.
3470
3471        Returns:
3472            The modified expression.
3473        """
3474        inst = maybe_copy(self, copy)
3475        inst.set(
3476            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3477        )
3478
3479        return inst
3480
3481    @property
3482    def named_selects(self) -> t.List[str]:
3483        return [e.output_name for e in self.expressions if e.alias_or_name]
3484
3485    @property
3486    def is_star(self) -> bool:
3487        return any(expression.is_star for expression in self.expressions)
3488
3489    @property
3490    def selects(self) -> t.List[Expression]:
3491        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
def from_( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2813    def from_(
2814        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2815    ) -> Select:
2816        """
2817        Set the FROM expression.
2818
2819        Example:
2820            >>> Select().from_("tbl").select("x").sql()
2821            'SELECT x FROM tbl'
2822
2823        Args:
2824            expression : the SQL code strings to parse.
2825                If a `From` instance is passed, this is used as-is.
2826                If another `Expression` instance is passed, it will be wrapped in a `From`.
2827            dialect: the dialect used to parse the input expression.
2828            copy: if `False`, modify this expression instance in-place.
2829            opts: other options to use to parse the input expressions.
2830
2831        Returns:
2832            The modified Select expression.
2833        """
2834        return _apply_builder(
2835            expression=expression,
2836            instance=self,
2837            arg="from",
2838            into=From,
2839            prefix="FROM",
2840            dialect=dialect,
2841            copy=copy,
2842            **opts,
2843        )

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 Expression 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[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2845    def group_by(
2846        self,
2847        *expressions: t.Optional[ExpOrStr],
2848        append: bool = True,
2849        dialect: DialectType = None,
2850        copy: bool = True,
2851        **opts,
2852    ) -> Select:
2853        """
2854        Set the GROUP BY expression.
2855
2856        Example:
2857            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2858            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2859
2860        Args:
2861            *expressions: the SQL code strings to parse.
2862                If a `Group` instance is passed, this is used as-is.
2863                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2864                If nothing is passed in then a group by is not applied to the expression
2865            append: if `True`, add to any existing expressions.
2866                Otherwise, this flattens all the `Group` expression into a single expression.
2867            dialect: the dialect used to parse the input expression.
2868            copy: if `False`, modify this expression instance in-place.
2869            opts: other options to use to parse the input expressions.
2870
2871        Returns:
2872            The modified Select expression.
2873        """
2874        if not expressions:
2875            return self if not copy else self.copy()
2876
2877        return _apply_child_list_builder(
2878            *expressions,
2879            instance=self,
2880            arg="group",
2881            append=append,
2882            copy=copy,
2883            prefix="GROUP BY",
2884            into=Group,
2885            dialect=dialect,
2886            **opts,
2887        )

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 Expression 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 order_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2889    def order_by(
2890        self,
2891        *expressions: t.Optional[ExpOrStr],
2892        append: bool = True,
2893        dialect: DialectType = None,
2894        copy: bool = True,
2895        **opts,
2896    ) -> Select:
2897        """
2898        Set the ORDER BY expression.
2899
2900        Example:
2901            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2902            'SELECT x FROM tbl ORDER BY x DESC'
2903
2904        Args:
2905            *expressions: the SQL code strings to parse.
2906                If a `Group` instance is passed, this is used as-is.
2907                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2908            append: if `True`, add to any existing expressions.
2909                Otherwise, this flattens all the `Order` expression into a single expression.
2910            dialect: the dialect used to parse the input expression.
2911            copy: if `False`, modify this expression instance in-place.
2912            opts: other options to use to parse the input expressions.
2913
2914        Returns:
2915            The modified Select expression.
2916        """
2917        return _apply_child_list_builder(
2918            *expressions,
2919            instance=self,
2920            arg="order",
2921            append=append,
2922            copy=copy,
2923            prefix="ORDER BY",
2924            into=Order,
2925            dialect=dialect,
2926            **opts,
2927        )

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 Expression 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 sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2929    def sort_by(
2930        self,
2931        *expressions: t.Optional[ExpOrStr],
2932        append: bool = True,
2933        dialect: DialectType = None,
2934        copy: bool = True,
2935        **opts,
2936    ) -> Select:
2937        """
2938        Set the SORT BY expression.
2939
2940        Example:
2941            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2942            'SELECT x FROM tbl SORT BY x DESC'
2943
2944        Args:
2945            *expressions: the SQL code strings to parse.
2946                If a `Group` instance is passed, this is used as-is.
2947                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2948            append: if `True`, add to any existing expressions.
2949                Otherwise, this flattens all the `Order` expression into a single expression.
2950            dialect: the dialect used to parse the input expression.
2951            copy: if `False`, modify this expression instance in-place.
2952            opts: other options to use to parse the input expressions.
2953
2954        Returns:
2955            The modified Select expression.
2956        """
2957        return _apply_child_list_builder(
2958            *expressions,
2959            instance=self,
2960            arg="sort",
2961            append=append,
2962            copy=copy,
2963            prefix="SORT BY",
2964            into=Sort,
2965            dialect=dialect,
2966            **opts,
2967        )

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 Expression 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[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2969    def cluster_by(
2970        self,
2971        *expressions: t.Optional[ExpOrStr],
2972        append: bool = True,
2973        dialect: DialectType = None,
2974        copy: bool = True,
2975        **opts,
2976    ) -> Select:
2977        """
2978        Set the CLUSTER BY expression.
2979
2980        Example:
2981            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2982            'SELECT x FROM tbl CLUSTER BY x DESC'
2983
2984        Args:
2985            *expressions: the SQL code strings to parse.
2986                If a `Group` instance is passed, this is used as-is.
2987                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2988            append: if `True`, add to any existing expressions.
2989                Otherwise, this flattens all the `Order` expression into a single expression.
2990            dialect: the dialect used to parse the input expression.
2991            copy: if `False`, modify this expression instance in-place.
2992            opts: other options to use to parse the input expressions.
2993
2994        Returns:
2995            The modified Select expression.
2996        """
2997        return _apply_child_list_builder(
2998            *expressions,
2999            instance=self,
3000            arg="cluster",
3001            append=append,
3002            copy=copy,
3003            prefix="CLUSTER BY",
3004            into=Cluster,
3005            dialect=dialect,
3006            **opts,
3007        )

Set the CLUSTER BY expression.

Example:
>>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl CLUSTER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression 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 limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3009    def limit(
3010        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3011    ) -> Select:
3012        """
3013        Set the LIMIT expression.
3014
3015        Example:
3016            >>> Select().from_("tbl").select("x").limit(10).sql()
3017            'SELECT x FROM tbl LIMIT 10'
3018
3019        Args:
3020            expression: the SQL code string to parse.
3021                This can also be an integer.
3022                If a `Limit` instance is passed, this is used as-is.
3023                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
3024            dialect: the dialect used to parse the input expression.
3025            copy: if `False`, modify this expression instance in-place.
3026            opts: other options to use to parse the input expressions.
3027
3028        Returns:
3029            Select: the modified expression.
3030        """
3031        return _apply_builder(
3032            expression=expression,
3033            instance=self,
3034            arg="limit",
3035            into=Limit,
3036            prefix="LIMIT",
3037            dialect=dialect,
3038            copy=copy,
3039            into_arg="expression",
3040            **opts,
3041        )

Set the LIMIT expression.

Example:
>>> Select().from_("tbl").select("x").limit(10).sql()
'SELECT x FROM tbl LIMIT 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, this is used as-is. If another Expression 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:

Select: the modified expression.

def offset( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3043    def offset(
3044        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3045    ) -> Select:
3046        """
3047        Set the OFFSET expression.
3048
3049        Example:
3050            >>> Select().from_("tbl").select("x").offset(10).sql()
3051            'SELECT x FROM tbl OFFSET 10'
3052
3053        Args:
3054            expression: the SQL code string to parse.
3055                This can also be an integer.
3056                If a `Offset` instance is passed, this is used as-is.
3057                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3058            dialect: the dialect used to parse the input expression.
3059            copy: if `False`, modify this expression instance in-place.
3060            opts: other options to use to parse the input expressions.
3061
3062        Returns:
3063            The modified Select expression.
3064        """
3065        return _apply_builder(
3066            expression=expression,
3067            instance=self,
3068            arg="offset",
3069            into=Offset,
3070            prefix="OFFSET",
3071            dialect=dialect,
3072            copy=copy,
3073            into_arg="expression",
3074            **opts,
3075        )

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 Expression 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 select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3077    def select(
3078        self,
3079        *expressions: t.Optional[ExpOrStr],
3080        append: bool = True,
3081        dialect: DialectType = None,
3082        copy: bool = True,
3083        **opts,
3084    ) -> Select:
3085        """
3086        Append to or set the SELECT expressions.
3087
3088        Example:
3089            >>> Select().select("x", "y").sql()
3090            'SELECT x, y'
3091
3092        Args:
3093            *expressions: the SQL code strings to parse.
3094                If an `Expression` instance is passed, it will be used as-is.
3095            append: if `True`, add to any existing expressions.
3096                Otherwise, this resets the expressions.
3097            dialect: the dialect used to parse the input expressions.
3098            copy: if `False`, modify this expression instance in-place.
3099            opts: other options to use to parse the input expressions.
3100
3101        Returns:
3102            The modified Select expression.
3103        """
3104        return _apply_list_builder(
3105            *expressions,
3106            instance=self,
3107            arg="expressions",
3108            append=append,
3109            dialect=dialect,
3110            copy=copy,
3111            **opts,
3112        )

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression 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 lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3114    def lateral(
3115        self,
3116        *expressions: t.Optional[ExpOrStr],
3117        append: bool = True,
3118        dialect: DialectType = None,
3119        copy: bool = True,
3120        **opts,
3121    ) -> Select:
3122        """
3123        Append to or set the LATERAL expressions.
3124
3125        Example:
3126            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3127            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3128
3129        Args:
3130            *expressions: the SQL code strings to parse.
3131                If an `Expression` instance is passed, it will be used as-is.
3132            append: if `True`, add to any existing expressions.
3133                Otherwise, this resets the expressions.
3134            dialect: the dialect used to parse the input expressions.
3135            copy: if `False`, modify this expression instance in-place.
3136            opts: other options to use to parse the input expressions.
3137
3138        Returns:
3139            The modified Select expression.
3140        """
3141        return _apply_list_builder(
3142            *expressions,
3143            instance=self,
3144            arg="laterals",
3145            append=append,
3146            into=Lateral,
3147            prefix="LATERAL VIEW",
3148            dialect=dialect,
3149            copy=copy,
3150            **opts,
3151        )

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 Expression 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[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3153    def join(
3154        self,
3155        expression: ExpOrStr,
3156        on: t.Optional[ExpOrStr] = None,
3157        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3158        append: bool = True,
3159        join_type: t.Optional[str] = None,
3160        join_alias: t.Optional[Identifier | str] = None,
3161        dialect: DialectType = None,
3162        copy: bool = True,
3163        **opts,
3164    ) -> Select:
3165        """
3166        Append to or set the JOIN expressions.
3167
3168        Example:
3169            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3170            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3171
3172            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3173            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3174
3175            Use `join_type` to change the type of join:
3176
3177            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3178            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3179
3180        Args:
3181            expression: the SQL code string to parse.
3182                If an `Expression` instance is passed, it will be used as-is.
3183            on: optionally specify the join "on" criteria as a SQL string.
3184                If an `Expression` instance is passed, it will be used as-is.
3185            using: optionally specify the join "using" criteria as a SQL string.
3186                If an `Expression` instance is passed, it will be used as-is.
3187            append: if `True`, add to any existing expressions.
3188                Otherwise, this resets the expressions.
3189            join_type: if set, alter the parsed join type.
3190            join_alias: an optional alias for the joined source.
3191            dialect: the dialect used to parse the input expressions.
3192            copy: if `False`, modify this expression instance in-place.
3193            opts: other options to use to parse the input expressions.
3194
3195        Returns:
3196            Select: the modified expression.
3197        """
3198        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3199
3200        try:
3201            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3202        except ParseError:
3203            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3204
3205        join = expression if isinstance(expression, Join) else Join(this=expression)
3206
3207        if isinstance(join.this, Select):
3208            join.this.replace(join.this.subquery())
3209
3210        if join_type:
3211            method: t.Optional[Token]
3212            side: t.Optional[Token]
3213            kind: t.Optional[Token]
3214
3215            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3216
3217            if method:
3218                join.set("method", method.text)
3219            if side:
3220                join.set("side", side.text)
3221            if kind:
3222                join.set("kind", kind.text)
3223
3224        if on:
3225            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3226            join.set("on", on)
3227
3228        if using:
3229            join = _apply_list_builder(
3230                *ensure_list(using),
3231                instance=join,
3232                arg="using",
3233                append=append,
3234                copy=copy,
3235                into=Identifier,
3236                **opts,
3237            )
3238
3239        if join_alias:
3240            join.set("this", alias_(join.this, join_alias, table=True))
3241
3242        return _apply_list_builder(
3243            join,
3244            instance=self,
3245            arg="joins",
3246            append=append,
3247            copy=copy,
3248            **opts,
3249        )

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 Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression 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 where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3251    def where(
3252        self,
3253        *expressions: t.Optional[ExpOrStr],
3254        append: bool = True,
3255        dialect: DialectType = None,
3256        copy: bool = True,
3257        **opts,
3258    ) -> Select:
3259        """
3260        Append to or set the WHERE expressions.
3261
3262        Example:
3263            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3264            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3265
3266        Args:
3267            *expressions: the SQL code strings to parse.
3268                If an `Expression` instance is passed, it will be used as-is.
3269                Multiple expressions are combined with an AND operator.
3270            append: if `True`, AND the new expressions to any existing expression.
3271                Otherwise, this resets the expression.
3272            dialect: the dialect used to parse the input expressions.
3273            copy: if `False`, modify this expression instance in-place.
3274            opts: other options to use to parse the input expressions.
3275
3276        Returns:
3277            Select: the modified expression.
3278        """
3279        return _apply_conjunction_builder(
3280            *expressions,
3281            instance=self,
3282            arg="where",
3283            append=append,
3284            into=Where,
3285            dialect=dialect,
3286            copy=copy,
3287            **opts,
3288        )

Append to or set the WHERE expressions.

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

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3290    def having(
3291        self,
3292        *expressions: t.Optional[ExpOrStr],
3293        append: bool = True,
3294        dialect: DialectType = None,
3295        copy: bool = True,
3296        **opts,
3297    ) -> Select:
3298        """
3299        Append to or set the HAVING expressions.
3300
3301        Example:
3302            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3303            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3304
3305        Args:
3306            *expressions: the SQL code strings to parse.
3307                If an `Expression` instance is passed, it will be used as-is.
3308                Multiple expressions are combined with an AND operator.
3309            append: if `True`, AND the new expressions to any existing expression.
3310                Otherwise, this resets the expression.
3311            dialect: the dialect used to parse the input expressions.
3312            copy: if `False`, modify this expression instance in-place.
3313            opts: other options to use to parse the input expressions.
3314
3315        Returns:
3316            The modified Select expression.
3317        """
3318        return _apply_conjunction_builder(
3319            *expressions,
3320            instance=self,
3321            arg="having",
3322            append=append,
3323            into=Having,
3324            dialect=dialect,
3325            copy=copy,
3326            **opts,
3327        )

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 Expression 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[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3329    def window(
3330        self,
3331        *expressions: t.Optional[ExpOrStr],
3332        append: bool = True,
3333        dialect: DialectType = None,
3334        copy: bool = True,
3335        **opts,
3336    ) -> Select:
3337        return _apply_list_builder(
3338            *expressions,
3339            instance=self,
3340            arg="windows",
3341            append=append,
3342            into=Window,
3343            dialect=dialect,
3344            copy=copy,
3345            **opts,
3346        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3348    def qualify(
3349        self,
3350        *expressions: t.Optional[ExpOrStr],
3351        append: bool = True,
3352        dialect: DialectType = None,
3353        copy: bool = True,
3354        **opts,
3355    ) -> Select:
3356        return _apply_conjunction_builder(
3357            *expressions,
3358            instance=self,
3359            arg="qualify",
3360            append=append,
3361            into=Qualify,
3362            dialect=dialect,
3363            copy=copy,
3364            **opts,
3365        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3367    def distinct(
3368        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3369    ) -> Select:
3370        """
3371        Set the OFFSET expression.
3372
3373        Example:
3374            >>> Select().from_("tbl").select("x").distinct().sql()
3375            'SELECT DISTINCT x FROM tbl'
3376
3377        Args:
3378            ons: the expressions to distinct on
3379            distinct: whether the Select should be distinct
3380            copy: if `False`, modify this expression instance in-place.
3381
3382        Returns:
3383            Select: the modified expression.
3384        """
3385        instance = maybe_copy(self, copy)
3386        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3387        instance.set("distinct", Distinct(on=on) if distinct else None)
3388        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[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
3390    def ctas(
3391        self,
3392        table: ExpOrStr,
3393        properties: t.Optional[t.Dict] = None,
3394        dialect: DialectType = None,
3395        copy: bool = True,
3396        **opts,
3397    ) -> Create:
3398        """
3399        Convert this expression to a CREATE TABLE AS statement.
3400
3401        Example:
3402            >>> Select().select("*").from_("tbl").ctas("x").sql()
3403            'CREATE TABLE x AS SELECT * FROM tbl'
3404
3405        Args:
3406            table: the SQL code string to parse as the table name.
3407                If another `Expression` instance is passed, it will be used as-is.
3408            properties: an optional mapping of table properties
3409            dialect: the dialect used to parse the input table.
3410            copy: if `False`, modify this expression instance in-place.
3411            opts: other options to use to parse the input table.
3412
3413        Returns:
3414            The new Create expression.
3415        """
3416        instance = maybe_copy(self, copy)
3417        table_expression = maybe_parse(
3418            table,
3419            into=Table,
3420            dialect=dialect,
3421            **opts,
3422        )
3423        properties_expression = None
3424        if properties:
3425            properties_expression = Properties.from_dict(properties)
3426
3427        return Create(
3428            this=table_expression,
3429            kind="TABLE",
3430            expression=instance,
3431            properties=properties_expression,
3432        )

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 Expression 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:
3434    def lock(self, update: bool = True, copy: bool = True) -> Select:
3435        """
3436        Set the locking read mode for this expression.
3437
3438        Examples:
3439            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3440            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3441
3442            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3443            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3444
3445        Args:
3446            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3447            copy: if `False`, modify this expression instance in-place.
3448
3449        Returns:
3450            The modified expression.
3451        """
3452        inst = maybe_copy(self, copy)
3453        inst.set("locks", [Lock(update=update)])
3454
3455        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[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
3457    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3458        """
3459        Set hints for this expression.
3460
3461        Examples:
3462            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3463            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3464
3465        Args:
3466            hints: The SQL code strings to parse as the hints.
3467                If an `Expression` instance is passed, it will be used as-is.
3468            dialect: The dialect used to parse the hints.
3469            copy: If `False`, modify this expression instance in-place.
3470
3471        Returns:
3472            The modified expression.
3473        """
3474        inst = maybe_copy(self, copy)
3475        inst.set(
3476            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3477        )
3478
3479        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 Expression 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]
3481    @property
3482    def named_selects(self) -> t.List[str]:
3483        return [e.output_name for e in self.expressions if e.alias_or_name]
is_star: bool
3485    @property
3486    def is_star(self) -> bool:
3487        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3489    @property
3490    def selects(self) -> t.List[Expression]:
3491        return self.expressions
key = 'select'
class Subquery(DerivedTable, Unionable):
3494class Subquery(DerivedTable, Unionable):
3495    arg_types = {
3496        "this": True,
3497        "alias": False,
3498        "with": False,
3499        **QUERY_MODIFIERS,
3500    }
3501
3502    def unnest(self):
3503        """
3504        Returns the first non subquery.
3505        """
3506        expression = self
3507        while isinstance(expression, Subquery):
3508            expression = expression.this
3509        return expression
3510
3511    def unwrap(self) -> Subquery:
3512        expression = self
3513        while expression.same_parent and expression.is_wrapper:
3514            expression = t.cast(Subquery, expression.parent)
3515        return expression
3516
3517    @property
3518    def is_wrapper(self) -> bool:
3519        """
3520        Whether this Subquery acts as a simple wrapper around another expression.
3521
3522        SELECT * FROM (((SELECT * FROM t)))
3523                      ^
3524                      This corresponds to a "wrapper" Subquery node
3525        """
3526        return all(v is None for k, v in self.args.items() if k != "this")
3527
3528    @property
3529    def is_star(self) -> bool:
3530        return self.this.is_star
3531
3532    @property
3533    def output_name(self) -> str:
3534        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
def unnest(self):
3502    def unnest(self):
3503        """
3504        Returns the first non subquery.
3505        """
3506        expression = self
3507        while isinstance(expression, Subquery):
3508            expression = expression.this
3509        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3511    def unwrap(self) -> Subquery:
3512        expression = self
3513        while expression.same_parent and expression.is_wrapper:
3514            expression = t.cast(Subquery, expression.parent)
3515        return expression
is_wrapper: bool
3517    @property
3518    def is_wrapper(self) -> bool:
3519        """
3520        Whether this Subquery acts as a simple wrapper around another expression.
3521
3522        SELECT * FROM (((SELECT * FROM t)))
3523                      ^
3524                      This corresponds to a "wrapper" Subquery node
3525        """
3526        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
3528    @property
3529    def is_star(self) -> bool:
3530        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3532    @property
3533    def output_name(self) -> str:
3534        return self.alias

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'subquery'
class TableSample(Expression):
3537class TableSample(Expression):
3538    arg_types = {
3539        "this": False,
3540        "expressions": False,
3541        "method": False,
3542        "bucket_numerator": False,
3543        "bucket_denominator": False,
3544        "bucket_field": False,
3545        "percent": False,
3546        "rows": False,
3547        "size": False,
3548        "seed": False,
3549    }
arg_types = {'this': False, 'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
3552class Tag(Expression):
3553    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3554
3555    arg_types = {
3556        "this": False,
3557        "prefix": False,
3558        "postfix": False,
3559    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3564class Pivot(Expression):
3565    arg_types = {
3566        "this": False,
3567        "alias": False,
3568        "expressions": False,
3569        "field": False,
3570        "unpivot": False,
3571        "using": False,
3572        "group": False,
3573        "columns": False,
3574        "include_nulls": False,
3575    }
3576
3577    @property
3578    def unpivot(self) -> bool:
3579        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3577    @property
3578    def unpivot(self) -> bool:
3579        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3582class Window(Condition):
3583    arg_types = {
3584        "this": True,
3585        "partition_by": False,
3586        "order": False,
3587        "spec": False,
3588        "alias": False,
3589        "over": False,
3590        "first": False,
3591    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3594class WindowSpec(Expression):
3595    arg_types = {
3596        "kind": False,
3597        "start": False,
3598        "start_side": False,
3599        "end": False,
3600        "end_side": False,
3601    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3604class Where(Expression):
3605    pass
key = 'where'
class Star(Expression):
3608class Star(Expression):
3609    arg_types = {"except": False, "replace": False}
3610
3611    @property
3612    def name(self) -> str:
3613        return "*"
3614
3615    @property
3616    def output_name(self) -> str:
3617        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3611    @property
3612    def name(self) -> str:
3613        return "*"
output_name: str
3615    @property
3616    def output_name(self) -> str:
3617        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'star'
class Parameter(Condition):
3620class Parameter(Condition):
3621    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3624class SessionParameter(Condition):
3625    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3628class Placeholder(Condition):
3629    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3632class Null(Condition):
3633    arg_types: t.Dict[str, t.Any] = {}
3634
3635    @property
3636    def name(self) -> str:
3637        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3635    @property
3636    def name(self) -> str:
3637        return "NULL"
key = 'null'
class Boolean(Condition):
3640class Boolean(Condition):
3641    pass
key = 'boolean'
class DataTypeParam(Expression):
3644class DataTypeParam(Expression):
3645    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3648class DataType(Expression):
3649    arg_types = {
3650        "this": True,
3651        "expressions": False,
3652        "nested": False,
3653        "values": False,
3654        "prefix": False,
3655        "kind": False,
3656    }
3657
3658    class Type(AutoName):
3659        ARRAY = auto()
3660        AGGREGATEFUNCTION = auto()
3661        SIMPLEAGGREGATEFUNCTION = auto()
3662        BIGDECIMAL = auto()
3663        BIGINT = auto()
3664        BIGSERIAL = auto()
3665        BINARY = auto()
3666        BIT = auto()
3667        BOOLEAN = auto()
3668        CHAR = auto()
3669        DATE = auto()
3670        DATE32 = auto()
3671        DATEMULTIRANGE = auto()
3672        DATERANGE = auto()
3673        DATETIME = auto()
3674        DATETIME64 = auto()
3675        DECIMAL = auto()
3676        DOUBLE = auto()
3677        ENUM = auto()
3678        ENUM8 = auto()
3679        ENUM16 = auto()
3680        FIXEDSTRING = auto()
3681        FLOAT = auto()
3682        GEOGRAPHY = auto()
3683        GEOMETRY = auto()
3684        HLLSKETCH = auto()
3685        HSTORE = auto()
3686        IMAGE = auto()
3687        INET = auto()
3688        INT = auto()
3689        INT128 = auto()
3690        INT256 = auto()
3691        INT4MULTIRANGE = auto()
3692        INT4RANGE = auto()
3693        INT8MULTIRANGE = auto()
3694        INT8RANGE = auto()
3695        INTERVAL = auto()
3696        IPADDRESS = auto()
3697        IPPREFIX = auto()
3698        IPV4 = auto()
3699        IPV6 = auto()
3700        JSON = auto()
3701        JSONB = auto()
3702        LONGBLOB = auto()
3703        LONGTEXT = auto()
3704        LOWCARDINALITY = auto()
3705        MAP = auto()
3706        MEDIUMBLOB = auto()
3707        MEDIUMINT = auto()
3708        MEDIUMTEXT = auto()
3709        MONEY = auto()
3710        NCHAR = auto()
3711        NESTED = auto()
3712        NULL = auto()
3713        NULLABLE = auto()
3714        NUMMULTIRANGE = auto()
3715        NUMRANGE = auto()
3716        NVARCHAR = auto()
3717        OBJECT = auto()
3718        ROWVERSION = auto()
3719        SERIAL = auto()
3720        SET = auto()
3721        SMALLINT = auto()
3722        SMALLMONEY = auto()
3723        SMALLSERIAL = auto()
3724        STRUCT = auto()
3725        SUPER = auto()
3726        TEXT = auto()
3727        TINYBLOB = auto()
3728        TINYTEXT = auto()
3729        TIME = auto()
3730        TIMETZ = auto()
3731        TIMESTAMP = auto()
3732        TIMESTAMPLTZ = auto()
3733        TIMESTAMPTZ = auto()
3734        TIMESTAMP_S = auto()
3735        TIMESTAMP_MS = auto()
3736        TIMESTAMP_NS = auto()
3737        TINYINT = auto()
3738        TSMULTIRANGE = auto()
3739        TSRANGE = auto()
3740        TSTZMULTIRANGE = auto()
3741        TSTZRANGE = auto()
3742        UBIGINT = auto()
3743        UINT = auto()
3744        UINT128 = auto()
3745        UINT256 = auto()
3746        UMEDIUMINT = auto()
3747        UDECIMAL = auto()
3748        UNIQUEIDENTIFIER = auto()
3749        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3750        USERDEFINED = "USER-DEFINED"
3751        USMALLINT = auto()
3752        UTINYINT = auto()
3753        UUID = auto()
3754        VARBINARY = auto()
3755        VARCHAR = auto()
3756        VARIANT = auto()
3757        XML = auto()
3758        YEAR = auto()
3759
3760    TEXT_TYPES = {
3761        Type.CHAR,
3762        Type.NCHAR,
3763        Type.VARCHAR,
3764        Type.NVARCHAR,
3765        Type.TEXT,
3766    }
3767
3768    INTEGER_TYPES = {
3769        Type.INT,
3770        Type.TINYINT,
3771        Type.SMALLINT,
3772        Type.BIGINT,
3773        Type.INT128,
3774        Type.INT256,
3775        Type.BIT,
3776    }
3777
3778    FLOAT_TYPES = {
3779        Type.FLOAT,
3780        Type.DOUBLE,
3781    }
3782
3783    NUMERIC_TYPES = {
3784        *INTEGER_TYPES,
3785        *FLOAT_TYPES,
3786    }
3787
3788    TEMPORAL_TYPES = {
3789        Type.TIME,
3790        Type.TIMETZ,
3791        Type.TIMESTAMP,
3792        Type.TIMESTAMPTZ,
3793        Type.TIMESTAMPLTZ,
3794        Type.TIMESTAMP_S,
3795        Type.TIMESTAMP_MS,
3796        Type.TIMESTAMP_NS,
3797        Type.DATE,
3798        Type.DATE32,
3799        Type.DATETIME,
3800        Type.DATETIME64,
3801    }
3802
3803    @classmethod
3804    def build(
3805        cls,
3806        dtype: DATA_TYPE,
3807        dialect: DialectType = None,
3808        udt: bool = False,
3809        **kwargs,
3810    ) -> DataType:
3811        """
3812        Constructs a DataType object.
3813
3814        Args:
3815            dtype: the data type of interest.
3816            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3817            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3818                DataType, thus creating a user-defined type.
3819            kawrgs: additional arguments to pass in the constructor of DataType.
3820
3821        Returns:
3822            The constructed DataType object.
3823        """
3824        from sqlglot import parse_one
3825
3826        if isinstance(dtype, str):
3827            if dtype.upper() == "UNKNOWN":
3828                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3829
3830            try:
3831                data_type_exp = parse_one(
3832                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3833                )
3834            except ParseError:
3835                if udt:
3836                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3837                raise
3838        elif isinstance(dtype, DataType.Type):
3839            data_type_exp = DataType(this=dtype)
3840        elif isinstance(dtype, DataType):
3841            return dtype
3842        else:
3843            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3844
3845        return DataType(**{**data_type_exp.args, **kwargs})
3846
3847    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3848        """
3849        Checks whether this DataType matches one of the provided data types. Nested types or precision
3850        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3851
3852        Args:
3853            dtypes: the data types to compare this DataType to.
3854
3855        Returns:
3856            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3857        """
3858        for dtype in dtypes:
3859            other = DataType.build(dtype, udt=True)
3860
3861            if (
3862                other.expressions
3863                or self.this == DataType.Type.USERDEFINED
3864                or other.this == DataType.Type.USERDEFINED
3865            ):
3866                matches = self == other
3867            else:
3868                matches = self.this == other.this
3869
3870            if matches:
3871                return True
3872        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.DOUBLE: 'DOUBLE'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, **kwargs) -> DataType:
3803    @classmethod
3804    def build(
3805        cls,
3806        dtype: DATA_TYPE,
3807        dialect: DialectType = None,
3808        udt: bool = False,
3809        **kwargs,
3810    ) -> DataType:
3811        """
3812        Constructs a DataType object.
3813
3814        Args:
3815            dtype: the data type of interest.
3816            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3817            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3818                DataType, thus creating a user-defined type.
3819            kawrgs: additional arguments to pass in the constructor of DataType.
3820
3821        Returns:
3822            The constructed DataType object.
3823        """
3824        from sqlglot import parse_one
3825
3826        if isinstance(dtype, str):
3827            if dtype.upper() == "UNKNOWN":
3828                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3829
3830            try:
3831                data_type_exp = parse_one(
3832                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3833                )
3834            except ParseError:
3835                if udt:
3836                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3837                raise
3838        elif isinstance(dtype, DataType.Type):
3839            data_type_exp = DataType(this=dtype)
3840        elif isinstance(dtype, DataType):
3841            return dtype
3842        else:
3843            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3844
3845        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • kawrgs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
3847    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3848        """
3849        Checks whether this DataType matches one of the provided data types. Nested types or precision
3850        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3851
3852        Args:
3853            dtypes: the data types to compare this DataType to.
3854
3855        Returns:
3856            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3857        """
3858        for dtype in dtypes:
3859            other = DataType.build(dtype, udt=True)
3860
3861            if (
3862                other.expressions
3863                or self.this == DataType.Type.USERDEFINED
3864                or other.this == DataType.Type.USERDEFINED
3865            ):
3866                matches = self == other
3867            else:
3868                matches = self.this == other.this
3869
3870            if matches:
3871                return True
3872        return False

Checks whether this DataType matches one of the provided data types. Nested types or precision will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this DataType to.
Returns:

True, if and only if there is a type in dtypes which is equal to this DataType.

key = 'datatype'
class DataType.Type(sqlglot.helper.AutoName):
3658    class Type(AutoName):
3659        ARRAY = auto()
3660        AGGREGATEFUNCTION = auto()
3661        SIMPLEAGGREGATEFUNCTION = auto()
3662        BIGDECIMAL = auto()
3663        BIGINT = auto()
3664        BIGSERIAL = auto()
3665        BINARY = auto()
3666        BIT = auto()
3667        BOOLEAN = auto()
3668        CHAR = auto()
3669        DATE = auto()
3670        DATE32 = auto()
3671        DATEMULTIRANGE = auto()
3672        DATERANGE = auto()
3673        DATETIME = auto()
3674        DATETIME64 = auto()
3675        DECIMAL = auto()
3676        DOUBLE = auto()
3677        ENUM = auto()
3678        ENUM8 = auto()
3679        ENUM16 = auto()
3680        FIXEDSTRING = auto()
3681        FLOAT = auto()
3682        GEOGRAPHY = auto()
3683        GEOMETRY = auto()
3684        HLLSKETCH = auto()
3685        HSTORE = auto()
3686        IMAGE = auto()
3687        INET = auto()
3688        INT = auto()
3689        INT128 = auto()
3690        INT256 = auto()
3691        INT4MULTIRANGE = auto()
3692        INT4RANGE = auto()
3693        INT8MULTIRANGE = auto()
3694        INT8RANGE = auto()
3695        INTERVAL = auto()
3696        IPADDRESS = auto()
3697        IPPREFIX = auto()
3698        IPV4 = auto()
3699        IPV6 = auto()
3700        JSON = auto()
3701        JSONB = auto()
3702        LONGBLOB = auto()
3703        LONGTEXT = auto()
3704        LOWCARDINALITY = auto()
3705        MAP = auto()
3706        MEDIUMBLOB = auto()
3707        MEDIUMINT = auto()
3708        MEDIUMTEXT = auto()
3709        MONEY = auto()
3710        NCHAR = auto()
3711        NESTED = auto()
3712        NULL = auto()
3713        NULLABLE = auto()
3714        NUMMULTIRANGE = auto()
3715        NUMRANGE = auto()
3716        NVARCHAR = auto()
3717        OBJECT = auto()
3718        ROWVERSION = auto()
3719        SERIAL = auto()
3720        SET = auto()
3721        SMALLINT = auto()
3722        SMALLMONEY = auto()
3723        SMALLSERIAL = auto()
3724        STRUCT = auto()
3725        SUPER = auto()
3726        TEXT = auto()
3727        TINYBLOB = auto()
3728        TINYTEXT = auto()
3729        TIME = auto()
3730        TIMETZ = auto()
3731        TIMESTAMP = auto()
3732        TIMESTAMPLTZ = auto()
3733        TIMESTAMPTZ = auto()
3734        TIMESTAMP_S = auto()
3735        TIMESTAMP_MS = auto()
3736        TIMESTAMP_NS = auto()
3737        TINYINT = auto()
3738        TSMULTIRANGE = auto()
3739        TSRANGE = auto()
3740        TSTZMULTIRANGE = auto()
3741        TSTZRANGE = auto()
3742        UBIGINT = auto()
3743        UINT = auto()
3744        UINT128 = auto()
3745        UINT256 = auto()
3746        UMEDIUMINT = auto()
3747        UDECIMAL = auto()
3748        UNIQUEIDENTIFIER = auto()
3749        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3750        USERDEFINED = "USER-DEFINED"
3751        USMALLINT = auto()
3752        UTINYINT = auto()
3753        UUID = auto()
3754        VARBINARY = auto()
3755        VARCHAR = auto()
3756        VARIANT = auto()
3757        XML = auto()
3758        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
3879class PseudoType(DataType):
3880    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3884class ObjectIdentifier(DataType):
3885    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3889class SubqueryPredicate(Predicate):
3890    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3893class All(SubqueryPredicate):
3894    pass
key = 'all'
class Any(SubqueryPredicate):
3897class Any(SubqueryPredicate):
3898    pass
key = 'any'
class Exists(SubqueryPredicate):
3901class Exists(SubqueryPredicate):
3902    pass
key = 'exists'
class Command(Expression):
3907class Command(Expression):
3908    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3911class Transaction(Expression):
3912    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3915class Commit(Expression):
3916    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3919class Rollback(Expression):
3920    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3923class AlterTable(Expression):
3924    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False}
key = 'altertable'
class AddConstraint(Expression):
3927class AddConstraint(Expression):
3928    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3931class DropPartition(Expression):
3932    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3936class Binary(Condition):
3937    arg_types = {"this": True, "expression": True}
3938
3939    @property
3940    def left(self) -> Expression:
3941        return self.this
3942
3943    @property
3944    def right(self) -> Expression:
3945        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3939    @property
3940    def left(self) -> Expression:
3941        return self.this
right: Expression
3943    @property
3944    def right(self) -> Expression:
3945        return self.expression
key = 'binary'
class Add(Binary):
3948class Add(Binary):
3949    pass
key = 'add'
class Connector(Binary):
3952class Connector(Binary):
3953    pass
key = 'connector'
class And(Connector):
3956class And(Connector):
3957    pass
key = 'and'
class Or(Connector):
3960class Or(Connector):
3961    pass
key = 'or'
class BitwiseAnd(Binary):
3964class BitwiseAnd(Binary):
3965    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3968class BitwiseLeftShift(Binary):
3969    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3972class BitwiseOr(Binary):
3973    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3976class BitwiseRightShift(Binary):
3977    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3980class BitwiseXor(Binary):
3981    pass
key = 'bitwisexor'
class Div(Binary):
3984class Div(Binary):
3985    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
arg_types = {'this': True, 'expression': True, 'typed': False, 'safe': False}
key = 'div'
class Overlaps(Binary):
3988class Overlaps(Binary):
3989    pass
key = 'overlaps'
class Dot(Binary):
3992class Dot(Binary):
3993    @property
3994    def name(self) -> str:
3995        return self.expression.name
3996
3997    @property
3998    def output_name(self) -> str:
3999        return self.name
4000
4001    @classmethod
4002    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4003        """Build a Dot object with a sequence of expressions."""
4004        if len(expressions) < 2:
4005            raise ValueError(f"Dot requires >= 2 expressions.")
4006
4007        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4008
4009    @property
4010    def parts(self) -> t.List[Expression]:
4011        """Return the parts of a table / column in order catalog, db, table."""
4012        this, *parts = self.flatten()
4013
4014        parts.reverse()
4015
4016        for arg in ("this", "table", "db", "catalog"):
4017            part = this.args.get(arg)
4018
4019            if isinstance(part, Expression):
4020                parts.append(part)
4021
4022        parts.reverse()
4023        return parts
name: str
3993    @property
3994    def name(self) -> str:
3995        return self.expression.name
output_name: str
3997    @property
3998    def output_name(self) -> str:
3999        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
@classmethod
def build( self, expressions: Sequence[Expression]) -> Dot:
4001    @classmethod
4002    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4003        """Build a Dot object with a sequence of expressions."""
4004        if len(expressions) < 2:
4005            raise ValueError(f"Dot requires >= 2 expressions.")
4006
4007        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
4009    @property
4010    def parts(self) -> t.List[Expression]:
4011        """Return the parts of a table / column in order catalog, db, table."""
4012        this, *parts = self.flatten()
4013
4014        parts.reverse()
4015
4016        for arg in ("this", "table", "db", "catalog"):
4017            part = this.args.get(arg)
4018
4019            if isinstance(part, Expression):
4020                parts.append(part)
4021
4022        parts.reverse()
4023        return parts

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

key = 'dot'
class DPipe(Binary):
4026class DPipe(Binary):
4027    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4030class EQ(Binary, Predicate):
4031    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4034class NullSafeEQ(Binary, Predicate):
4035    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4038class NullSafeNEQ(Binary, Predicate):
4039    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4043class PropertyEQ(Binary):
4044    pass
key = 'propertyeq'
class Distance(Binary):
4047class Distance(Binary):
4048    pass
key = 'distance'
class Escape(Binary):
4051class Escape(Binary):
4052    pass
key = 'escape'
class Glob(Binary, Predicate):
4055class Glob(Binary, Predicate):
4056    pass
key = 'glob'
class GT(Binary, Predicate):
4059class GT(Binary, Predicate):
4060    pass
key = 'gt'
class GTE(Binary, Predicate):
4063class GTE(Binary, Predicate):
4064    pass
key = 'gte'
class ILike(Binary, Predicate):
4067class ILike(Binary, Predicate):
4068    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4071class ILikeAny(Binary, Predicate):
4072    pass
key = 'ilikeany'
class IntDiv(Binary):
4075class IntDiv(Binary):
4076    pass
key = 'intdiv'
class Is(Binary, Predicate):
4079class Is(Binary, Predicate):
4080    pass
key = 'is'
class Kwarg(Binary):
4083class Kwarg(Binary):
4084    """Kwarg in special functions like func(kwarg => y)."""

Kwarg in special functions like func(kwarg => y).

key = 'kwarg'
class Like(Binary, Predicate):
4087class Like(Binary, Predicate):
4088    pass
key = 'like'
class LikeAny(Binary, Predicate):
4091class LikeAny(Binary, Predicate):
4092    pass
key = 'likeany'
class LT(Binary, Predicate):
4095class LT(Binary, Predicate):
4096    pass
key = 'lt'
class LTE(Binary, Predicate):
4099class LTE(Binary, Predicate):
4100    pass
key = 'lte'
class Mod(Binary):
4103class Mod(Binary):
4104    pass
key = 'mod'
class Mul(Binary):
4107class Mul(Binary):
4108    pass
key = 'mul'
class NEQ(Binary, Predicate):
4111class NEQ(Binary, Predicate):
4112    pass
key = 'neq'
class Operator(Binary):
4116class Operator(Binary):
4117    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4120class SimilarTo(Binary, Predicate):
4121    pass
key = 'similarto'
class Slice(Binary):
4124class Slice(Binary):
4125    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4128class Sub(Binary):
4129    pass
key = 'sub'
class ArrayOverlaps(Binary):
4132class ArrayOverlaps(Binary):
4133    pass
key = 'arrayoverlaps'
class Unary(Condition):
4138class Unary(Condition):
4139    pass
key = 'unary'
class BitwiseNot(Unary):
4142class BitwiseNot(Unary):
4143    pass
key = 'bitwisenot'
class Not(Unary):
4146class Not(Unary):
4147    pass
key = 'not'
class Paren(Unary):
4150class Paren(Unary):
4151    arg_types = {"this": True, "with": False}
4152
4153    @property
4154    def output_name(self) -> str:
4155        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4153    @property
4154    def output_name(self) -> str:
4155        return self.this.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'paren'
class Neg(Unary):
4158class Neg(Unary):
4159    pass
key = 'neg'
class Alias(Expression):
4162class Alias(Expression):
4163    arg_types = {"this": True, "alias": False}
4164
4165    @property
4166    def output_name(self) -> str:
4167        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4165    @property
4166    def output_name(self) -> str:
4167        return self.alias

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'alias'
class PivotAlias(Alias):
4172class PivotAlias(Alias):
4173    pass
key = 'pivotalias'
class Aliases(Expression):
4176class Aliases(Expression):
4177    arg_types = {"this": True, "expressions": True}
4178
4179    @property
4180    def aliases(self):
4181        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4179    @property
4180    def aliases(self):
4181        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4185class AtIndex(Expression):
4186    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4189class AtTimeZone(Expression):
4190    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4193class FromTimeZone(Expression):
4194    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4197class Between(Predicate):
4198    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4201class Bracket(Condition):
4202    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4203    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4204
4205    @property
4206    def output_name(self) -> str:
4207        if len(self.expressions) == 1:
4208            return self.expressions[0].output_name
4209
4210        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4205    @property
4206    def output_name(self) -> str:
4207        if len(self.expressions) == 1:
4208            return self.expressions[0].output_name
4209
4210        return super().output_name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'bracket'
class Distinct(Expression):
4213class Distinct(Expression):
4214    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4217class In(Predicate):
4218    arg_types = {
4219        "this": True,
4220        "expressions": False,
4221        "query": False,
4222        "unnest": False,
4223        "field": False,
4224        "is_global": False,
4225    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4229class ForIn(Expression):
4230    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4233class TimeUnit(Expression):
4234    """Automatically converts unit arg into a var."""
4235
4236    arg_types = {"unit": False}
4237
4238    UNABBREVIATED_UNIT_NAME = {
4239        "D": "DAY",
4240        "H": "HOUR",
4241        "M": "MINUTE",
4242        "MS": "MILLISECOND",
4243        "NS": "NANOSECOND",
4244        "Q": "QUARTER",
4245        "S": "SECOND",
4246        "US": "MICROSECOND",
4247        "W": "WEEK",
4248        "Y": "YEAR",
4249    }
4250
4251    VAR_LIKE = (Column, Literal, Var)
4252
4253    def __init__(self, **args):
4254        unit = args.get("unit")
4255        if isinstance(unit, self.VAR_LIKE):
4256            args["unit"] = Var(
4257                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4258            )
4259        elif isinstance(unit, Week):
4260            unit.set("this", Var(this=unit.this.name.upper()))
4261
4262        super().__init__(**args)
4263
4264    @property
4265    def unit(self) -> t.Optional[Var]:
4266        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4253    def __init__(self, **args):
4254        unit = args.get("unit")
4255        if isinstance(unit, self.VAR_LIKE):
4256            args["unit"] = Var(
4257                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4258            )
4259        elif isinstance(unit, Week):
4260            unit.set("this", Var(this=unit.this.name.upper()))
4261
4262        super().__init__(**args)
arg_types = {'unit': False}
UNABBREVIATED_UNIT_NAME = {'D': 'DAY', 'H': 'HOUR', 'M': 'MINUTE', 'MS': 'MILLISECOND', 'NS': 'NANOSECOND', 'Q': 'QUARTER', 'S': 'SECOND', 'US': 'MICROSECOND', 'W': 'WEEK', 'Y': 'YEAR'}
VAR_LIKE = (<class 'Column'>, <class 'Literal'>, <class 'Var'>)
unit: Optional[Var]
4264    @property
4265    def unit(self) -> t.Optional[Var]:
4266        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4269class IntervalOp(TimeUnit):
4270    arg_types = {"unit": True, "expression": True}
4271
4272    def interval(self):
4273        return Interval(
4274            this=self.expression.copy(),
4275            unit=self.unit.copy(),
4276        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4272    def interval(self):
4273        return Interval(
4274            this=self.expression.copy(),
4275            unit=self.unit.copy(),
4276        )
key = 'intervalop'
class IntervalSpan(DataType):
4282class IntervalSpan(DataType):
4283    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4286class Interval(TimeUnit):
4287    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4290class IgnoreNulls(Expression):
4291    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4294class RespectNulls(Expression):
4295    pass
key = 'respectnulls'
class Func(Condition):
4299class Func(Condition):
4300    """
4301    The base class for all function expressions.
4302
4303    Attributes:
4304        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4305            treated as a variable length argument and the argument's value will be stored as a list.
4306        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4307            for this function expression. These values are used to map this node to a name during parsing
4308            as well as to provide the function's name during SQL string generation. By default the SQL
4309            name is set to the expression's class name transformed to snake case.
4310    """
4311
4312    is_var_len_args = False
4313
4314    @classmethod
4315    def from_arg_list(cls, args):
4316        if cls.is_var_len_args:
4317            all_arg_keys = list(cls.arg_types)
4318            # If this function supports variable length argument treat the last argument as such.
4319            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4320            num_non_var = len(non_var_len_arg_keys)
4321
4322            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4323            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4324        else:
4325            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4326
4327        return cls(**args_dict)
4328
4329    @classmethod
4330    def sql_names(cls):
4331        if cls is Func:
4332            raise NotImplementedError(
4333                "SQL name is only supported by concrete function implementations"
4334            )
4335        if "_sql_names" not in cls.__dict__:
4336            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4337        return cls._sql_names
4338
4339    @classmethod
4340    def sql_name(cls):
4341        return cls.sql_names()[0]
4342
4343    @classmethod
4344    def default_parser_mappings(cls):
4345        return {name: cls.from_arg_list for name in cls.sql_names()}

The base class for all function expressions.

Attributes:
  • is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
  • _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
is_var_len_args = False
@classmethod
def from_arg_list(cls, args):
4314    @classmethod
4315    def from_arg_list(cls, args):
4316        if cls.is_var_len_args:
4317            all_arg_keys = list(cls.arg_types)
4318            # If this function supports variable length argument treat the last argument as such.
4319            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4320            num_non_var = len(non_var_len_arg_keys)
4321
4322            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4323            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4324        else:
4325            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4326
4327        return cls(**args_dict)
@classmethod
def sql_names(cls):
4329    @classmethod
4330    def sql_names(cls):
4331        if cls is Func:
4332            raise NotImplementedError(
4333                "SQL name is only supported by concrete function implementations"
4334            )
4335        if "_sql_names" not in cls.__dict__:
4336            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4337        return cls._sql_names
@classmethod
def sql_name(cls):
4339    @classmethod
4340    def sql_name(cls):
4341        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4343    @classmethod
4344    def default_parser_mappings(cls):
4345        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4348class AggFunc(Func):
4349    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4352class ParameterizedAgg(AggFunc):
4353    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4356class Abs(Func):
4357    pass
key = 'abs'
class ArgMax(AggFunc):
4360class ArgMax(AggFunc):
4361    arg_types = {"this": True, "expression": True, "count": False}
4362    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4365class ArgMin(AggFunc):
4366    arg_types = {"this": True, "expression": True, "count": False}
4367    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4370class ApproxTopK(AggFunc):
4371    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4374class Flatten(Func):
4375    pass
key = 'flatten'
class Transform(Func):
4379class Transform(Func):
4380    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4383class Anonymous(Func):
4384    arg_types = {"this": True, "expressions": False}
4385    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4388class AnonymousAggFunc(AggFunc):
4389    arg_types = {"this": True, "expressions": False}
4390    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4394class CombinedAggFunc(AnonymousAggFunc):
4395    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4398class CombinedParameterizedAgg(ParameterizedAgg):
4399    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
4404class Hll(AggFunc):
4405    arg_types = {"this": True, "expressions": False}
4406    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4409class ApproxDistinct(AggFunc):
4410    arg_types = {"this": True, "accuracy": False}
4411    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4414class Array(Func):
4415    arg_types = {"expressions": False}
4416    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4420class ToArray(Func):
4421    pass
key = 'toarray'
class ToChar(Func):
4426class ToChar(Func):
4427    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4430class GenerateSeries(Func):
4431    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4434class ArrayAgg(AggFunc):
4435    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4438class ArrayUniqueAgg(AggFunc):
4439    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4442class ArrayAll(Func):
4443    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4446class ArrayAny(Func):
4447    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4450class ArrayConcat(Func):
4451    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4452    arg_types = {"this": True, "expressions": False}
4453    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4456class ArrayContains(Binary, Func):
4457    pass
key = 'arraycontains'
class ArrayContained(Binary):
4460class ArrayContained(Binary):
4461    pass
key = 'arraycontained'
class ArrayFilter(Func):
4464class ArrayFilter(Func):
4465    arg_types = {"this": True, "expression": True}
4466    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4469class ArrayJoin(Func):
4470    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4473class ArraySize(Func):
4474    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4477class ArraySort(Func):
4478    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4481class ArraySum(Func):
4482    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4485class ArrayUnionAgg(AggFunc):
4486    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4489class Avg(AggFunc):
4490    pass
key = 'avg'
class AnyValue(AggFunc):
4493class AnyValue(AggFunc):
4494    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
arg_types = {'this': True, 'having': False, 'max': False, 'ignore_nulls': False}
key = 'anyvalue'
class First(Func):
4497class First(Func):
4498    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4501class Last(Func):
4502    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4505class Case(Func):
4506    arg_types = {"this": False, "ifs": True, "default": False}
4507
4508    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4509        instance = maybe_copy(self, copy)
4510        instance.append(
4511            "ifs",
4512            If(
4513                this=maybe_parse(condition, copy=copy, **opts),
4514                true=maybe_parse(then, copy=copy, **opts),
4515            ),
4516        )
4517        return instance
4518
4519    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4520        instance = maybe_copy(self, copy)
4521        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4522        return instance
arg_types = {'this': False, 'ifs': True, 'default': False}
def when( self, condition: Union[str, Expression], then: Union[str, Expression], copy: bool = True, **opts) -> Case:
4508    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4509        instance = maybe_copy(self, copy)
4510        instance.append(
4511            "ifs",
4512            If(
4513                this=maybe_parse(condition, copy=copy, **opts),
4514                true=maybe_parse(then, copy=copy, **opts),
4515            ),
4516        )
4517        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4519    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4520        instance = maybe_copy(self, copy)
4521        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4522        return instance
key = 'case'
class Cast(Func):
4525class Cast(Func):
4526    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4527
4528    @property
4529    def name(self) -> str:
4530        return self.this.name
4531
4532    @property
4533    def to(self) -> DataType:
4534        return self.args["to"]
4535
4536    @property
4537    def output_name(self) -> str:
4538        return self.name
4539
4540    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4541        """
4542        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4543        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4544        array<int> != array<float>.
4545
4546        Args:
4547            dtypes: the data types to compare this Cast's DataType to.
4548
4549        Returns:
4550            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4551        """
4552        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4528    @property
4529    def name(self) -> str:
4530        return self.this.name
to: DataType
4532    @property
4533    def to(self) -> DataType:
4534        return self.args["to"]
output_name: str
4536    @property
4537    def output_name(self) -> str:
4538        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4540    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4541        """
4542        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4543        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4544        array<int> != array<float>.
4545
4546        Args:
4547            dtypes: the data types to compare this Cast's DataType to.
4548
4549        Returns:
4550            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4551        """
4552        return self.to.is_type(*dtypes)

Checks whether this Cast's DataType matches one of the provided data types. Nested types like arrays or structs will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this Cast's DataType to.
Returns:

True, if and only if there is a type in dtypes which is equal to this Cast's DataType.

key = 'cast'
class TryCast(Cast):
4555class TryCast(Cast):
4556    pass
key = 'trycast'
class CastToStrType(Func):
4559class CastToStrType(Func):
4560    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4563class Collate(Binary, Func):
4564    pass
key = 'collate'
class Ceil(Func):
4567class Ceil(Func):
4568    arg_types = {"this": True, "decimals": False}
4569    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4572class Coalesce(Func):
4573    arg_types = {"this": True, "expressions": False}
4574    is_var_len_args = True
4575    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4578class Chr(Func):
4579    arg_types = {"this": True, "charset": False, "expressions": False}
4580    is_var_len_args = True
4581    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4584class Concat(Func):
4585    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4586    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4589class ConcatWs(Concat):
4590    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4593class Count(AggFunc):
4594    arg_types = {"this": False, "expressions": False}
4595    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4598class CountIf(AggFunc):
4599    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4602class CurrentDate(Func):
4603    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4606class CurrentDatetime(Func):
4607    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4610class CurrentTime(Func):
4611    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4614class CurrentTimestamp(Func):
4615    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4618class CurrentUser(Func):
4619    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4622class DateAdd(Func, IntervalOp):
4623    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4626class DateSub(Func, IntervalOp):
4627    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4630class DateDiff(Func, TimeUnit):
4631    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4632    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4635class DateTrunc(Func):
4636    arg_types = {"unit": True, "this": True, "zone": False}
4637
4638    def __init__(self, **args):
4639        unit = args.get("unit")
4640        if isinstance(unit, TimeUnit.VAR_LIKE):
4641            args["unit"] = Literal.string(
4642                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4643            )
4644        elif isinstance(unit, Week):
4645            unit.set("this", Literal.string(unit.this.name.upper()))
4646
4647        super().__init__(**args)
4648
4649    @property
4650    def unit(self) -> Expression:
4651        return self.args["unit"]
DateTrunc(**args)
4638    def __init__(self, **args):
4639        unit = args.get("unit")
4640        if isinstance(unit, TimeUnit.VAR_LIKE):
4641            args["unit"] = Literal.string(
4642                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4643            )
4644        elif isinstance(unit, Week):
4645            unit.set("this", Literal.string(unit.this.name.upper()))
4646
4647        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4649    @property
4650    def unit(self) -> Expression:
4651        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4654class DatetimeAdd(Func, IntervalOp):
4655    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4658class DatetimeSub(Func, IntervalOp):
4659    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4662class DatetimeDiff(Func, TimeUnit):
4663    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4666class DatetimeTrunc(Func, TimeUnit):
4667    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4670class DayOfWeek(Func):
4671    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4674class DayOfMonth(Func):
4675    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4678class DayOfYear(Func):
4679    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4682class ToDays(Func):
4683    pass
key = 'todays'
class WeekOfYear(Func):
4686class WeekOfYear(Func):
4687    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4690class MonthsBetween(Func):
4691    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4694class LastDay(Func, TimeUnit):
4695    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4696    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4699class Extract(Func):
4700    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4703class Timestamp(Func):
4704    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4707class TimestampAdd(Func, TimeUnit):
4708    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4711class TimestampSub(Func, TimeUnit):
4712    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4715class TimestampDiff(Func, TimeUnit):
4716    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4719class TimestampTrunc(Func, TimeUnit):
4720    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4723class TimeAdd(Func, TimeUnit):
4724    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4727class TimeSub(Func, TimeUnit):
4728    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4731class TimeDiff(Func, TimeUnit):
4732    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4735class TimeTrunc(Func, TimeUnit):
4736    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4739class DateFromParts(Func):
4740    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4741    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4744class TimeFromParts(Func):
4745    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4746    arg_types = {
4747        "hour": True,
4748        "min": True,
4749        "sec": True,
4750        "nano": False,
4751        "fractions": False,
4752        "precision": False,
4753    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4756class DateStrToDate(Func):
4757    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4760class DateToDateStr(Func):
4761    pass
key = 'datetodatestr'
class DateToDi(Func):
4764class DateToDi(Func):
4765    pass
key = 'datetodi'
class Date(Func):
4769class Date(Func):
4770    arg_types = {"this": False, "zone": False, "expressions": False}
4771    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4774class Day(Func):
4775    pass
key = 'day'
class Decode(Func):
4778class Decode(Func):
4779    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4782class DiToDate(Func):
4783    pass
key = 'ditodate'
class Encode(Func):
4786class Encode(Func):
4787    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4790class Exp(Func):
4791    pass
key = 'exp'
class Explode(Func):
4795class Explode(Func):
4796    arg_types = {"this": True, "expressions": False}
4797    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4800class ExplodeOuter(Explode):
4801    pass
key = 'explodeouter'
class Posexplode(Explode):
4804class Posexplode(Explode):
4805    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4808class PosexplodeOuter(Posexplode):
4809    pass
key = 'posexplodeouter'
class Floor(Func):
4812class Floor(Func):
4813    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4816class FromBase64(Func):
4817    pass
key = 'frombase64'
class ToBase64(Func):
4820class ToBase64(Func):
4821    pass
key = 'tobase64'
class Greatest(Func):
4824class Greatest(Func):
4825    arg_types = {"this": True, "expressions": False}
4826    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4829class GroupConcat(AggFunc):
4830    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4833class Hex(Func):
4834    pass
key = 'hex'
class Xor(Connector, Func):
4837class Xor(Connector, Func):
4838    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4841class If(Func):
4842    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4845class Nullif(Func):
4846    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4849class Initcap(Func):
4850    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4853class IsNan(Func):
4854    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4857class IsInf(Func):
4858    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4861class FormatJson(Expression):
4862    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4865class JSONKeyValue(Expression):
4866    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4869class JSONObject(Func):
4870    arg_types = {
4871        "expressions": False,
4872        "null_handling": False,
4873        "unique_keys": False,
4874        "return_type": False,
4875        "encoding": False,
4876    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
4879class JSONObjectAgg(AggFunc):
4880    arg_types = {
4881        "expressions": False,
4882        "null_handling": False,
4883        "unique_keys": False,
4884        "return_type": False,
4885        "encoding": False,
4886    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
4890class JSONArray(Func):
4891    arg_types = {
4892        "expressions": True,
4893        "null_handling": False,
4894        "return_type": False,
4895        "strict": False,
4896    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4900class JSONArrayAgg(Func):
4901    arg_types = {
4902        "this": True,
4903        "order": False,
4904        "null_handling": False,
4905        "return_type": False,
4906        "strict": False,
4907    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4912class JSONColumnDef(Expression):
4913    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False}
key = 'jsoncolumndef'
class JSONSchema(Expression):
4916class JSONSchema(Expression):
4917    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4921class JSONTable(Func):
4922    arg_types = {
4923        "this": True,
4924        "schema": True,
4925        "path": False,
4926        "error_handling": False,
4927        "empty_handling": False,
4928    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4931class OpenJSONColumnDef(Expression):
4932    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
arg_types = {'this': True, 'kind': True, 'path': False, 'as_json': False}
key = 'openjsoncolumndef'
class OpenJSON(Func):
4935class OpenJSON(Func):
4936    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4939class JSONBContains(Binary):
4940    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4943class JSONExtract(Binary, Func):
4944    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4947class JSONExtractScalar(JSONExtract):
4948    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4951class JSONBExtract(JSONExtract):
4952    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4955class JSONBExtractScalar(JSONExtract):
4956    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4959class JSONFormat(Func):
4960    arg_types = {"this": False, "options": False}
4961    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4965class JSONArrayContains(Binary, Predicate, Func):
4966    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4969class ParseJSON(Func):
4970    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4971    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4972    arg_types = {"this": True, "expressions": False}
4973    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class GetPath(Func):
4977class GetPath(Func):
4978    arg_types = {"this": True, "expression": True}
4979
4980    @property
4981    def output_name(self) -> str:
4982        return self.expression.output_name
arg_types = {'this': True, 'expression': True}
output_name: str
4980    @property
4981    def output_name(self) -> str:
4982        return self.expression.output_name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'getpath'
class Least(Func):
4985class Least(Func):
4986    arg_types = {"this": True, "expressions": False}
4987    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4990class Left(Func):
4991    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4998class Length(Func):
4999    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5002class Levenshtein(Func):
5003    arg_types = {
5004        "this": True,
5005        "expression": False,
5006        "ins_cost": False,
5007        "del_cost": False,
5008        "sub_cost": False,
5009    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5012class Ln(Func):
5013    pass
key = 'ln'
class Log(Func):
5016class Log(Func):
5017    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5020class Log2(Func):
5021    pass
key = 'log2'
class Log10(Func):
5024class Log10(Func):
5025    pass
key = 'log10'
class LogicalOr(AggFunc):
5028class LogicalOr(AggFunc):
5029    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5032class LogicalAnd(AggFunc):
5033    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5036class Lower(Func):
5037    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5040class Map(Func):
5041    arg_types = {"keys": False, "values": False}
5042
5043    @property
5044    def keys(self) -> t.List[Expression]:
5045        keys = self.args.get("keys")
5046        return keys.expressions if keys else []
5047
5048    @property
5049    def values(self) -> t.List[Expression]:
5050        values = self.args.get("values")
5051        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5043    @property
5044    def keys(self) -> t.List[Expression]:
5045        keys = self.args.get("keys")
5046        return keys.expressions if keys else []
values: List[Expression]
5048    @property
5049    def values(self) -> t.List[Expression]:
5050        values = self.args.get("values")
5051        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5054class MapFromEntries(Func):
5055    pass
key = 'mapfromentries'
class StarMap(Func):
5058class StarMap(Func):
5059    pass
key = 'starmap'
class VarMap(Func):
5062class VarMap(Func):
5063    arg_types = {"keys": True, "values": True}
5064    is_var_len_args = True
5065
5066    @property
5067    def keys(self) -> t.List[Expression]:
5068        return self.args["keys"].expressions
5069
5070    @property
5071    def values(self) -> t.List[Expression]:
5072        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5066    @property
5067    def keys(self) -> t.List[Expression]:
5068        return self.args["keys"].expressions
values: List[Expression]
5070    @property
5071    def values(self) -> t.List[Expression]:
5072        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5076class MatchAgainst(Func):
5077    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5080class Max(AggFunc):
5081    arg_types = {"this": True, "expressions": False}
5082    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5085class MD5(Func):
5086    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5090class MD5Digest(Func):
5091    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5094class Min(AggFunc):
5095    arg_types = {"this": True, "expressions": False}
5096    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5099class Month(Func):
5100    pass
key = 'month'
class Nvl2(Func):
5103class Nvl2(Func):
5104    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5108class Predict(Func):
5109    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5112class Pow(Binary, Func):
5113    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5116class PercentileCont(AggFunc):
5117    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5120class PercentileDisc(AggFunc):
5121    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5124class Quantile(AggFunc):
5125    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5128class ApproxQuantile(Quantile):
5129    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Rand(Func):
5132class Rand(Func):
5133    _sql_names = ["RAND", "RANDOM"]
5134    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5137class Randn(Func):
5138    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5141class RangeN(Func):
5142    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5145class ReadCSV(Func):
5146    _sql_names = ["READ_CSV"]
5147    is_var_len_args = True
5148    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5151class Reduce(Func):
5152    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
arg_types = {'this': True, 'initial': True, 'merge': True, 'finish': False}
key = 'reduce'
class RegexpExtract(Func):
5155class RegexpExtract(Func):
5156    arg_types = {
5157        "this": True,
5158        "expression": True,
5159        "position": False,
5160        "occurrence": False,
5161        "parameters": False,
5162        "group": False,
5163    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5166class RegexpReplace(Func):
5167    arg_types = {
5168        "this": True,
5169        "expression": True,
5170        "replacement": False,
5171        "position": False,
5172        "occurrence": False,
5173        "parameters": False,
5174        "modifiers": False,
5175    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5178class RegexpLike(Binary, Func):
5179    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5182class RegexpILike(Binary, Func):
5183    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5188class RegexpSplit(Func):
5189    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5192class Repeat(Func):
5193    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5198class Round(Func):
5199    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5202class RowNumber(Func):
5203    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5206class SafeDivide(Func):
5207    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5210class SHA(Func):
5211    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5214class SHA2(Func):
5215    _sql_names = ["SHA2"]
5216    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5219class SortArray(Func):
5220    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5223class Split(Func):
5224    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5229class Substring(Func):
5230    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5233class StandardHash(Func):
5234    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5237class StartsWith(Func):
5238    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5239    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5242class StrPosition(Func):
5243    arg_types = {
5244        "this": True,
5245        "substr": True,
5246        "position": False,
5247        "instance": False,
5248    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5251class StrToDate(Func):
5252    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5255class StrToTime(Func):
5256    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5261class StrToUnix(Func):
5262    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5267class StrToMap(Func):
5268    arg_types = {
5269        "this": True,
5270        "pair_delim": False,
5271        "key_value_delim": False,
5272        "duplicate_resolution_callback": False,
5273    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5276class NumberToStr(Func):
5277    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5280class FromBase(Func):
5281    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5284class Struct(Func):
5285    arg_types = {"expressions": False}
5286    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5289class StructExtract(Func):
5290    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5295class Stuff(Func):
5296    _sql_names = ["STUFF", "INSERT"]
5297    arg_types = {"this": True, "start": True, "length": True, "expression": True}
arg_types = {'this': True, 'start': True, 'length': True, 'expression': True}
key = 'stuff'
class Sum(AggFunc):
5300class Sum(AggFunc):
5301    pass
key = 'sum'
class Sqrt(Func):
5304class Sqrt(Func):
5305    pass
key = 'sqrt'
class Stddev(AggFunc):
5308class Stddev(AggFunc):
5309    pass
key = 'stddev'
class StddevPop(AggFunc):
5312class StddevPop(AggFunc):
5313    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5316class StddevSamp(AggFunc):
5317    pass
key = 'stddevsamp'
class TimeToStr(Func):
5320class TimeToStr(Func):
5321    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5324class TimeToTimeStr(Func):
5325    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5328class TimeToUnix(Func):
5329    pass
key = 'timetounix'
class TimeStrToDate(Func):
5332class TimeStrToDate(Func):
5333    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5336class TimeStrToTime(Func):
5337    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5340class TimeStrToUnix(Func):
5341    pass
key = 'timestrtounix'
class Trim(Func):
5344class Trim(Func):
5345    arg_types = {
5346        "this": True,
5347        "expression": False,
5348        "position": False,
5349        "collation": False,
5350    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5353class TsOrDsAdd(Func, TimeUnit):
5354    # return_type is used to correctly cast the arguments of this expression when transpiling it
5355    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5356
5357    @property
5358    def return_type(self) -> DataType:
5359        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
arg_types = {'this': True, 'expression': True, 'unit': False, 'return_type': False}
return_type: DataType
5357    @property
5358    def return_type(self) -> DataType:
5359        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5362class TsOrDsDiff(Func, TimeUnit):
5363    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5366class TsOrDsToDateStr(Func):
5367    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5370class TsOrDsToDate(Func):
5371    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5374class TsOrDsToTime(Func):
5375    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5378class TsOrDiToDi(Func):
5379    pass
key = 'tsorditodi'
class Unhex(Func):
5382class Unhex(Func):
5383    pass
key = 'unhex'
class UnixDate(Func):
5387class UnixDate(Func):
5388    pass
key = 'unixdate'
class UnixToStr(Func):
5391class UnixToStr(Func):
5392    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5397class UnixToTime(Func):
5398    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5399
5400    SECONDS = Literal.number(0)
5401    DECIS = Literal.number(1)
5402    CENTIS = Literal.number(2)
5403    MILLIS = Literal.number(3)
5404    DECIMILLIS = Literal.number(4)
5405    CENTIMILLIS = Literal.number(5)
5406    MICROS = Literal.number(6)
5407    DECIMICROS = Literal.number(7)
5408    CENTIMICROS = Literal.number(8)
5409    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False}
SECONDS = Literal(this=0, is_string=False)
DECIS = Literal(this=1, is_string=False)
CENTIS = Literal(this=2, is_string=False)
MILLIS = Literal(this=3, is_string=False)
DECIMILLIS = Literal(this=4, is_string=False)
CENTIMILLIS = Literal(this=5, is_string=False)
MICROS = Literal(this=6, is_string=False)
DECIMICROS = Literal(this=7, is_string=False)
CENTIMICROS = Literal(this=8, is_string=False)
NANOS = Literal(this=9, is_string=False)
key = 'unixtotime'
class UnixToTimeStr(Func):
5412class UnixToTimeStr(Func):
5413    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5416class TimestampFromParts(Func):
5417    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5418    arg_types = {
5419        "year": True,
5420        "month": True,
5421        "day": True,
5422        "hour": True,
5423        "min": True,
5424        "sec": True,
5425        "nano": False,
5426        "zone": False,
5427        "milli": False,
5428    }
arg_types = {'year': True, 'month': True, 'day': True, 'hour': True, 'min': True, 'sec': True, 'nano': False, 'zone': False, 'milli': False}
key = 'timestampfromparts'
class Upper(Func):
5431class Upper(Func):
5432    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5435class Variance(AggFunc):
5436    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5439class VariancePop(AggFunc):
5440    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5443class Week(Func):
5444    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5447class XMLTable(Func):
5448    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
arg_types = {'this': True, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class Year(Func):
5451class Year(Func):
5452    pass
key = 'year'
class Use(Expression):
5455class Use(Expression):
5456    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5459class Merge(Expression):
5460    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5463class When(Func):
5464    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class NextValueFor(Func):
5469class NextValueFor(Func):
5470    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'GetPath'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Last'>, <class 'LastDay'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_JOIN': <class 'ArrayJoin'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GET_PATH': <class 'GetPath'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOG10': <class 'Log10'>, 'LOG2': <class 'Log2'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
5506def maybe_parse(
5507    sql_or_expression: ExpOrStr,
5508    *,
5509    into: t.Optional[IntoType] = None,
5510    dialect: DialectType = None,
5511    prefix: t.Optional[str] = None,
5512    copy: bool = False,
5513    **opts,
5514) -> Expression:
5515    """Gracefully handle a possible string or expression.
5516
5517    Example:
5518        >>> maybe_parse("1")
5519        Literal(this=1, is_string=False)
5520        >>> maybe_parse(to_identifier("x"))
5521        Identifier(this=x, quoted=False)
5522
5523    Args:
5524        sql_or_expression: the SQL code string or an expression
5525        into: the SQLGlot Expression to parse into
5526        dialect: the dialect used to parse the input expressions (in the case that an
5527            input expression is a SQL string).
5528        prefix: a string to prefix the sql with before it gets parsed
5529            (automatically includes a space)
5530        copy: whether or not to copy the expression.
5531        **opts: other options to use to parse the input expressions (again, in the case
5532            that an input expression is a SQL string).
5533
5534    Returns:
5535        Expression: the parsed or given expression.
5536    """
5537    if isinstance(sql_or_expression, Expression):
5538        if copy:
5539            return sql_or_expression.copy()
5540        return sql_or_expression
5541
5542    if sql_or_expression is None:
5543        raise ParseError(f"SQL cannot be None")
5544
5545    import sqlglot
5546
5547    sql = str(sql_or_expression)
5548    if prefix:
5549        sql = f"{prefix} {sql}"
5550
5551    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)

Gracefully handle a possible string or expression.

Example:
>>> maybe_parse("1")
Literal(this=1, is_string=False)
>>> maybe_parse(to_identifier("x"))
Identifier(this=x, quoted=False)
Arguments:
  • sql_or_expression: the SQL code string or an expression
  • into: the SQLGlot Expression to parse into
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • prefix: a string to prefix the sql with before it gets parsed (automatically includes a space)
  • copy: whether or not to copy the expression.
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Expression: the parsed or given expression.

def maybe_copy(instance, copy=True):
5562def maybe_copy(instance, copy=True):
5563    return instance.copy() if copy and instance else instance
def union( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
5777def union(
5778    left: ExpOrStr,
5779    right: ExpOrStr,
5780    distinct: bool = True,
5781    dialect: DialectType = None,
5782    copy: bool = True,
5783    **opts,
5784) -> Union:
5785    """
5786    Initializes a syntax tree from one UNION expression.
5787
5788    Example:
5789        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5790        'SELECT * FROM foo UNION SELECT * FROM bla'
5791
5792    Args:
5793        left: the SQL code string corresponding to the left-hand side.
5794            If an `Expression` instance is passed, it will be used as-is.
5795        right: the SQL code string corresponding to the right-hand side.
5796            If an `Expression` instance is passed, it will be used as-is.
5797        distinct: set the DISTINCT flag if and only if this is true.
5798        dialect: the dialect used to parse the input expression.
5799        copy: whether or not to copy the expression.
5800        opts: other options to use to parse the input expressions.
5801
5802    Returns:
5803        The new Union instance.
5804    """
5805    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5806    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5807
5808    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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 or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
5811def intersect(
5812    left: ExpOrStr,
5813    right: ExpOrStr,
5814    distinct: bool = True,
5815    dialect: DialectType = None,
5816    copy: bool = True,
5817    **opts,
5818) -> Intersect:
5819    """
5820    Initializes a syntax tree from one INTERSECT expression.
5821
5822    Example:
5823        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5824        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5825
5826    Args:
5827        left: the SQL code string corresponding to the left-hand side.
5828            If an `Expression` instance is passed, it will be used as-is.
5829        right: the SQL code string corresponding to the right-hand side.
5830            If an `Expression` instance is passed, it will be used as-is.
5831        distinct: set the DISTINCT flag if and only if this is true.
5832        dialect: the dialect used to parse the input expression.
5833        copy: whether or not to copy the expression.
5834        opts: other options to use to parse the input expressions.
5835
5836    Returns:
5837        The new Intersect instance.
5838    """
5839    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5840    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5841
5842    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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 or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
5845def except_(
5846    left: ExpOrStr,
5847    right: ExpOrStr,
5848    distinct: bool = True,
5849    dialect: DialectType = None,
5850    copy: bool = True,
5851    **opts,
5852) -> Except:
5853    """
5854    Initializes a syntax tree from one EXCEPT expression.
5855
5856    Example:
5857        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5858        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5859
5860    Args:
5861        left: the SQL code string corresponding to the left-hand side.
5862            If an `Expression` instance is passed, it will be used as-is.
5863        right: the SQL code string corresponding to the right-hand side.
5864            If an `Expression` instance is passed, it will be used as-is.
5865        distinct: set the DISTINCT flag if and only if this is true.
5866        dialect: the dialect used to parse the input expression.
5867        copy: whether or not to copy the expression.
5868        opts: other options to use to parse the input expressions.
5869
5870    Returns:
5871        The new Except instance.
5872    """
5873    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5874    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5875
5876    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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 or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
5879def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5880    """
5881    Initializes a syntax tree from one or multiple SELECT expressions.
5882
5883    Example:
5884        >>> select("col1", "col2").from_("tbl").sql()
5885        'SELECT col1, col2 FROM tbl'
5886
5887    Args:
5888        *expressions: the SQL code string to parse as the expressions of a
5889            SELECT statement. If an Expression instance is passed, this is used as-is.
5890        dialect: the dialect used to parse the input expressions (in the case that an
5891            input expression is a SQL string).
5892        **opts: other options to use to parse the input expressions (again, in the case
5893            that an input expression is a SQL string).
5894
5895    Returns:
5896        Select: the syntax tree for the SELECT statement.
5897    """
5898    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

Example:
>>> select("col1", "col2").from_("tbl").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expressions: the SQL code string to parse as the expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
5901def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5902    """
5903    Initializes a syntax tree from a FROM expression.
5904
5905    Example:
5906        >>> from_("tbl").select("col1", "col2").sql()
5907        'SELECT col1, col2 FROM tbl'
5908
5909    Args:
5910        *expression: the SQL code string to parse as the FROM expressions of a
5911            SELECT statement. If an Expression instance is passed, this is used as-is.
5912        dialect: the dialect used to parse the input expression (in the case that the
5913            input expression is a SQL string).
5914        **opts: other options to use to parse the input expressions (again, in the case
5915            that the input expression is a SQL string).
5916
5917    Returns:
5918        Select: the syntax tree for the SELECT statement.
5919    """
5920    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

Example:
>>> from_("tbl").select("col1", "col2").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expression: the SQL code string to parse as the FROM expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: dict, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Update:
5923def update(
5924    table: str | Table,
5925    properties: dict,
5926    where: t.Optional[ExpOrStr] = None,
5927    from_: t.Optional[ExpOrStr] = None,
5928    dialect: DialectType = None,
5929    **opts,
5930) -> Update:
5931    """
5932    Creates an update statement.
5933
5934    Example:
5935        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5936        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5937
5938    Args:
5939        *properties: dictionary of properties to set which are
5940            auto converted to sql objects eg None -> NULL
5941        where: sql conditional parsed into a WHERE statement
5942        from_: sql statement parsed into a FROM statement
5943        dialect: the dialect used to parse the input expressions.
5944        **opts: other options to use to parse the input expressions.
5945
5946    Returns:
5947        Update: the syntax tree for the UPDATE statement.
5948    """
5949    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5950    update_expr.set(
5951        "expressions",
5952        [
5953            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5954            for k, v in properties.items()
5955        ],
5956    )
5957    if from_:
5958        update_expr.set(
5959            "from",
5960            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5961        )
5962    if isinstance(where, Condition):
5963        where = Where(this=where)
5964    if where:
5965        update_expr.set(
5966            "where",
5967            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5968        )
5969    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
"UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
Arguments:
  • *properties: dictionary of properties to set which are auto converted to sql objects eg None -> NULL
  • where: sql conditional parsed into a WHERE statement
  • from_: sql statement parsed into a FROM statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Delete:
5972def delete(
5973    table: ExpOrStr,
5974    where: t.Optional[ExpOrStr] = None,
5975    returning: t.Optional[ExpOrStr] = None,
5976    dialect: DialectType = None,
5977    **opts,
5978) -> Delete:
5979    """
5980    Builds a delete statement.
5981
5982    Example:
5983        >>> delete("my_table", where="id > 1").sql()
5984        'DELETE FROM my_table WHERE id > 1'
5985
5986    Args:
5987        where: sql conditional parsed into a WHERE statement
5988        returning: sql conditional parsed into a RETURNING statement
5989        dialect: the dialect used to parse the input expressions.
5990        **opts: other options to use to parse the input expressions.
5991
5992    Returns:
5993        Delete: the syntax tree for the DELETE statement.
5994    """
5995    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5996    if where:
5997        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5998    if returning:
5999        delete_expr = t.cast(
6000            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6001        )
6002    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
6005def insert(
6006    expression: ExpOrStr,
6007    into: ExpOrStr,
6008    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6009    overwrite: t.Optional[bool] = None,
6010    returning: t.Optional[ExpOrStr] = None,
6011    dialect: DialectType = None,
6012    copy: bool = True,
6013    **opts,
6014) -> Insert:
6015    """
6016    Builds an INSERT statement.
6017
6018    Example:
6019        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6020        'INSERT INTO tbl VALUES (1, 2, 3)'
6021
6022    Args:
6023        expression: the sql string or expression of the INSERT statement
6024        into: the tbl to insert data to.
6025        columns: optionally the table's column names.
6026        overwrite: whether to INSERT OVERWRITE or not.
6027        returning: sql conditional parsed into a RETURNING statement
6028        dialect: the dialect used to parse the input expressions.
6029        copy: whether or not to copy the expression.
6030        **opts: other options to use to parse the input expressions.
6031
6032    Returns:
6033        Insert: the syntax tree for the INSERT statement.
6034    """
6035    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6036    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6037
6038    if columns:
6039        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6040
6041    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6042
6043    if returning:
6044        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6045
6046    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether or not to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6049def condition(
6050    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6051) -> Condition:
6052    """
6053    Initialize a logical condition expression.
6054
6055    Example:
6056        >>> condition("x=1").sql()
6057        'x = 1'
6058
6059        This is helpful for composing larger logical syntax trees:
6060        >>> where = condition("x=1")
6061        >>> where = where.and_("y=1")
6062        >>> Select().from_("tbl").select("*").where(where).sql()
6063        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6064
6065    Args:
6066        *expression: the SQL code string to parse.
6067            If an Expression instance is passed, this is used as-is.
6068        dialect: the dialect used to parse the input expression (in the case that the
6069            input expression is a SQL string).
6070        copy: Whether or not to copy `expression` (only applies to expressions).
6071        **opts: other options to use to parse the input expressions (again, in the case
6072            that the input expression is a SQL string).
6073
6074    Returns:
6075        The new Condition instance
6076    """
6077    return maybe_parse(
6078        expression,
6079        into=Condition,
6080        dialect=dialect,
6081        copy=copy,
6082        **opts,
6083    )

Initialize a logical condition expression.

Example:
>>> condition("x=1").sql()
'x = 1'

This is helpful for composing larger logical syntax trees:

>>> where = condition("x=1")
>>> where = where.and_("y=1")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • copy: Whether or not to copy expression (only applies to expressions).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6086def and_(
6087    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6088) -> Condition:
6089    """
6090    Combine multiple conditions with an AND logical operator.
6091
6092    Example:
6093        >>> and_("x=1", and_("y=1", "z=1")).sql()
6094        'x = 1 AND (y = 1 AND z = 1)'
6095
6096    Args:
6097        *expressions: the SQL code strings to parse.
6098            If an Expression instance is passed, this is used as-is.
6099        dialect: the dialect used to parse the input expression.
6100        copy: whether or not to copy `expressions` (only applies to Expressions).
6101        **opts: other options to use to parse the input expressions.
6102
6103    Returns:
6104        And: the new condition
6105    """
6106    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))

Combine multiple conditions with an AND logical operator.

Example:
>>> and_("x=1", and_("y=1", "z=1")).sql()
'x = 1 AND (y = 1 AND z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

And: the new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6109def or_(
6110    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6111) -> Condition:
6112    """
6113    Combine multiple conditions with an OR logical operator.
6114
6115    Example:
6116        >>> or_("x=1", or_("y=1", "z=1")).sql()
6117        'x = 1 OR (y = 1 OR z = 1)'
6118
6119    Args:
6120        *expressions: the SQL code strings to parse.
6121            If an Expression instance is passed, this is used as-is.
6122        dialect: the dialect used to parse the input expression.
6123        copy: whether or not to copy `expressions` (only applies to Expressions).
6124        **opts: other options to use to parse the input expressions.
6125
6126    Returns:
6127        Or: the new condition
6128    """
6129    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))

Combine multiple conditions with an OR logical operator.

Example:
>>> or_("x=1", or_("y=1", "z=1")).sql()
'x = 1 OR (y = 1 OR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

Or: the new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
6132def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6133    """
6134    Wrap a condition with a NOT operator.
6135
6136    Example:
6137        >>> not_("this_suit='black'").sql()
6138        "NOT this_suit = 'black'"
6139
6140    Args:
6141        expression: the SQL code string to parse.
6142            If an Expression instance is passed, this is used as-is.
6143        dialect: the dialect used to parse the input expression.
6144        copy: whether to copy the expression or not.
6145        **opts: other options to use to parse the input expressions.
6146
6147    Returns:
6148        The new condition.
6149    """
6150    this = condition(
6151        expression,
6152        dialect=dialect,
6153        copy=copy,
6154        **opts,
6155    )
6156    return Not(this=_wrap(this, Connector))

Wrap a condition with a NOT operator.

Example:
>>> not_("this_suit='black'").sql()
"NOT this_suit = 'black'"
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression or not.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition.

def paren( expression: Union[str, Expression], copy: bool = True) -> Paren:
6159def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6160    """
6161    Wrap an expression in parentheses.
6162
6163    Example:
6164        >>> paren("5 + 3").sql()
6165        '(5 + 3)'
6166
6167    Args:
6168        expression: the SQL code string to parse.
6169            If an Expression instance is passed, this is used as-is.
6170        copy: whether to copy the expression or not.
6171
6172    Returns:
6173        The wrapped expression.
6174    """
6175    return Paren(this=maybe_parse(expression, copy=copy))

Wrap an expression in parentheses.

Example:
>>> paren("5 + 3").sql()
'(5 + 3)'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • copy: whether to copy the expression or not.
Returns:

The wrapped expression.

SAFE_IDENTIFIER_RE = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
6191def to_identifier(name, quoted=None, copy=True):
6192    """Builds an identifier.
6193
6194    Args:
6195        name: The name to turn into an identifier.
6196        quoted: Whether or not force quote the identifier.
6197        copy: Whether or not to copy name if it's an Identifier.
6198
6199    Returns:
6200        The identifier ast node.
6201    """
6202
6203    if name is None:
6204        return None
6205
6206    if isinstance(name, Identifier):
6207        identifier = maybe_copy(name, copy)
6208    elif isinstance(name, str):
6209        identifier = Identifier(
6210            this=name,
6211            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6212        )
6213    else:
6214        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6215    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether or not force quote the identifier.
  • copy: Whether or not to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
6218def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6219    """
6220    Parses a given string into an identifier.
6221
6222    Args:
6223        name: The name to parse into an identifier.
6224        dialect: The dialect to parse against.
6225
6226    Returns:
6227        The identifier ast node.
6228    """
6229    try:
6230        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6231    except ParseError:
6232        expression = to_identifier(name)
6233
6234    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*([0-9]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
6240def to_interval(interval: str | Literal) -> Interval:
6241    """Builds an interval expression from a string like '1 day' or '5 months'."""
6242    if isinstance(interval, Literal):
6243        if not interval.is_string:
6244            raise ValueError("Invalid interval string.")
6245
6246        interval = interval.this
6247
6248    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6249
6250    if not interval_parts:
6251        raise ValueError("Invalid interval string.")
6252
6253    return Interval(
6254        this=Literal.string(interval_parts.group(1)),
6255        unit=Var(this=interval_parts.group(2).upper()),
6256    )

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: Union[str, Table, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Optional[Table]:
6267def to_table(
6268    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6269) -> t.Optional[Table]:
6270    """
6271    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6272    If a table is passed in then that table is returned.
6273
6274    Args:
6275        sql_path: a `[catalog].[schema].[table]` string.
6276        dialect: the source dialect according to which the table name will be parsed.
6277        copy: Whether or not to copy a table if it is passed in.
6278        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6279
6280    Returns:
6281        A table expression.
6282    """
6283    if sql_path is None or isinstance(sql_path, Table):
6284        return maybe_copy(sql_path, copy=copy)
6285    if not isinstance(sql_path, str):
6286        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6287
6288    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6289    if table:
6290        for k, v in kwargs.items():
6291            table.set(k, v)
6292
6293    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether or not to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
6296def to_column(sql_path: str | Column, **kwargs) -> Column:
6297    """
6298    Create a column from a `[table].[column]` sql path. Schema is optional.
6299
6300    If a column is passed in then that column is returned.
6301
6302    Args:
6303        sql_path: `[table].[column]` string
6304    Returns:
6305        Table: A column expression
6306    """
6307    if sql_path is None or isinstance(sql_path, Column):
6308        return sql_path
6309    if not isinstance(sql_path, str):
6310        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6311    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore

Create a column from a [table].[column] sql path. Schema is optional.

If a column is passed in then that column is returned.

Arguments:
  • sql_path: [table].[column] string
Returns:

Table: A column expression

def alias_( expression: Union[str, Expression], alias: str | Identifier, table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
6314def alias_(
6315    expression: ExpOrStr,
6316    alias: str | Identifier,
6317    table: bool | t.Sequence[str | Identifier] = False,
6318    quoted: t.Optional[bool] = None,
6319    dialect: DialectType = None,
6320    copy: bool = True,
6321    **opts,
6322):
6323    """Create an Alias expression.
6324
6325    Example:
6326        >>> alias_('foo', 'bar').sql()
6327        'foo AS bar'
6328
6329        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6330        '(SELECT 1, 2) AS bar(a, b)'
6331
6332    Args:
6333        expression: the SQL code strings to parse.
6334            If an Expression instance is passed, this is used as-is.
6335        alias: the alias name to use. If the name has
6336            special characters it is quoted.
6337        table: Whether or not to create a table alias, can also be a list of columns.
6338        quoted: whether or not to quote the alias
6339        dialect: the dialect used to parse the input expression.
6340        copy: Whether or not to copy the expression.
6341        **opts: other options to use to parse the input expressions.
6342
6343    Returns:
6344        Alias: the aliased expression
6345    """
6346    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6347    alias = to_identifier(alias, quoted=quoted)
6348
6349    if table:
6350        table_alias = TableAlias(this=alias)
6351        exp.set("alias", table_alias)
6352
6353        if not isinstance(table, bool):
6354            for column in table:
6355                table_alias.append("columns", to_identifier(column, quoted=quoted))
6356
6357        return exp
6358
6359    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6360    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6361    # for the complete Window expression.
6362    #
6363    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6364
6365    if "alias" in exp.arg_types and not isinstance(exp, Window):
6366        exp.set("alias", alias)
6367        return exp
6368    return Alias(this=exp, alias=alias)

Create an Alias expression.

Example:
>>> alias_('foo', 'bar').sql()
'foo AS bar'
>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
'(SELECT 1, 2) AS bar(a, b)'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use. If the name has special characters it is quoted.
  • table: Whether or not to create a table alias, can also be a list of columns.
  • quoted: whether or not to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether or not to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6371def subquery(
6372    expression: ExpOrStr,
6373    alias: t.Optional[Identifier | str] = None,
6374    dialect: DialectType = None,
6375    **opts,
6376) -> Select:
6377    """
6378    Build a subquery expression.
6379
6380    Example:
6381        >>> subquery('select x from tbl', 'bar').select('x').sql()
6382        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6383
6384    Args:
6385        expression: the SQL code strings to parse.
6386            If an Expression instance is passed, this is used as-is.
6387        alias: the alias name to use.
6388        dialect: the dialect used to parse the input expression.
6389        **opts: other options to use to parse the input expressions.
6390
6391    Returns:
6392        A new Select instance with the subquery expression included.
6393    """
6394
6395    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6396    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression.

Example:
>>> subquery('select x from tbl', 'bar').select('x').sql()
'SELECT x FROM (SELECT x FROM tbl) AS bar'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use.
  • dialect: the dialect used to parse the input expression.
  • **opts: other options to use to parse the input expressions.
Returns:

A new Select instance with the subquery expression included.

def column( col, table=None, db=None, catalog=None, *, fields=None, quoted=None, copy=True):
6427def column(
6428    col,
6429    table=None,
6430    db=None,
6431    catalog=None,
6432    *,
6433    fields=None,
6434    quoted=None,
6435    copy=True,
6436):
6437    """
6438    Build a Column.
6439
6440    Args:
6441        col: Column name.
6442        table: Table name.
6443        db: Database name.
6444        catalog: Catalog name.
6445        fields: Additional fields using dots.
6446        quoted: Whether to force quotes on the column's identifiers.
6447        copy: Whether or not to copy identifiers if passed in.
6448
6449    Returns:
6450        The new Column instance.
6451    """
6452    this = Column(
6453        this=to_identifier(col, quoted=quoted, copy=copy),
6454        table=to_identifier(table, quoted=quoted, copy=copy),
6455        db=to_identifier(db, quoted=quoted, copy=copy),
6456        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6457    )
6458
6459    if fields:
6460        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6461    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether or not to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], **opts) -> Cast:
6464def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6465    """Cast an expression to a data type.
6466
6467    Example:
6468        >>> cast('x + 1', 'int').sql()
6469        'CAST(x + 1 AS INT)'
6470
6471    Args:
6472        expression: The expression to cast.
6473        to: The datatype to cast to.
6474
6475    Returns:
6476        The new Cast instance.
6477    """
6478    expression = maybe_parse(expression, **opts)
6479    data_type = DataType.build(to, **opts)
6480    expression = Cast(this=expression, to=data_type)
6481    expression.type = data_type
6482    return expression

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
6485def table_(
6486    table: Identifier | str,
6487    db: t.Optional[Identifier | str] = None,
6488    catalog: t.Optional[Identifier | str] = None,
6489    quoted: t.Optional[bool] = None,
6490    alias: t.Optional[Identifier | str] = None,
6491) -> Table:
6492    """Build a Table.
6493
6494    Args:
6495        table: Table name.
6496        db: Database name.
6497        catalog: Catalog name.
6498        quote: Whether to force quotes on the table's identifiers.
6499        alias: Table's alias.
6500
6501    Returns:
6502        The new Table instance.
6503    """
6504    return Table(
6505        this=to_identifier(table, quoted=quoted) if table else None,
6506        db=to_identifier(db, quoted=quoted) if db else None,
6507        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6508        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6509    )

Build a Table.

Arguments:
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • quote: Whether to force quotes on the table's identifiers.
  • alias: Table's alias.
Returns:

The new Table instance.

def values( values: Iterable[Tuple[Any, ...]], alias: Optional[str] = None, columns: Union[Iterable[str], Dict[str, DataType], NoneType] = None) -> Values:
6512def values(
6513    values: t.Iterable[t.Tuple[t.Any, ...]],
6514    alias: t.Optional[str] = None,
6515    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6516) -> Values:
6517    """Build VALUES statement.
6518
6519    Example:
6520        >>> values([(1, '2')]).sql()
6521        "VALUES (1, '2')"
6522
6523    Args:
6524        values: values statements that will be converted to SQL
6525        alias: optional alias
6526        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6527         If either are provided then an alias is also required.
6528
6529    Returns:
6530        Values: the Values expression object
6531    """
6532    if columns and not alias:
6533        raise ValueError("Alias is required when providing columns")
6534
6535    return Values(
6536        expressions=[convert(tup) for tup in values],
6537        alias=(
6538            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6539            if columns
6540            else (TableAlias(this=to_identifier(alias)) if alias else None)
6541        ),
6542    )

Build VALUES statement.

Example:
>>> values([(1, '2')]).sql()
"VALUES (1, '2')"
Arguments:
  • values: values statements that will be converted to SQL
  • alias: optional alias
  • columns: Optional list of ordered column names or ordered dictionary of column names to types. If either are provided then an alias is also required.
Returns:

Values: the Values expression object

def var( name: Union[str, Expression, NoneType]) -> Var:
6545def var(name: t.Optional[ExpOrStr]) -> Var:
6546    """Build a SQL variable.
6547
6548    Example:
6549        >>> repr(var('x'))
6550        'Var(this=x)'
6551
6552        >>> repr(var(column('x', table='y')))
6553        'Var(this=x)'
6554
6555    Args:
6556        name: The name of the var or an expression who's name will become the var.
6557
6558    Returns:
6559        The new variable node.
6560    """
6561    if not name:
6562        raise ValueError("Cannot convert empty name into var.")
6563
6564    if isinstance(name, Expression):
6565        name = name.name
6566    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table) -> AlterTable:
6569def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6570    """Build ALTER TABLE... RENAME... expression
6571
6572    Args:
6573        old_name: The old name of the table
6574        new_name: The new name of the table
6575
6576    Returns:
6577        Alter table expression
6578    """
6579    old_table = to_table(old_name)
6580    new_table = to_table(new_name)
6581    return AlterTable(
6582        this=old_table,
6583        actions=[
6584            RenameTable(this=new_table),
6585        ],
6586    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None) -> AlterTable:
6589def rename_column(
6590    table_name: str | Table,
6591    old_column_name: str | Column,
6592    new_column_name: str | Column,
6593    exists: t.Optional[bool] = None,
6594) -> AlterTable:
6595    """Build ALTER TABLE... RENAME COLUMN... expression
6596
6597    Args:
6598        table_name: Name of the table
6599        old_column: The old name of the column
6600        new_column: The new name of the column
6601        exists: Whether or not to add the `IF EXISTS` clause
6602
6603    Returns:
6604        Alter table expression
6605    """
6606    table = to_table(table_name)
6607    old_column = to_column(old_column_name)
6608    new_column = to_column(new_column_name)
6609    return AlterTable(
6610        this=table,
6611        actions=[
6612            RenameColumn(this=old_column, to=new_column, exists=exists),
6613        ],
6614    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether or not to add the IF EXISTS clause
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
6617def convert(value: t.Any, copy: bool = False) -> Expression:
6618    """Convert a python value into an expression object.
6619
6620    Raises an error if a conversion is not possible.
6621
6622    Args:
6623        value: A python object.
6624        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6625
6626    Returns:
6627        Expression: the equivalent expression object.
6628    """
6629    if isinstance(value, Expression):
6630        return maybe_copy(value, copy)
6631    if isinstance(value, str):
6632        return Literal.string(value)
6633    if isinstance(value, bool):
6634        return Boolean(this=value)
6635    if value is None or (isinstance(value, float) and math.isnan(value)):
6636        return null()
6637    if isinstance(value, numbers.Number):
6638        return Literal.number(value)
6639    if isinstance(value, datetime.datetime):
6640        datetime_literal = Literal.string(
6641            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6642        )
6643        return TimeStrToTime(this=datetime_literal)
6644    if isinstance(value, datetime.date):
6645        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6646        return DateStrToDate(this=date_literal)
6647    if isinstance(value, tuple):
6648        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6649    if isinstance(value, list):
6650        return Array(expressions=[convert(v, copy=copy) for v in value])
6651    if isinstance(value, dict):
6652        return Map(
6653            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6654            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6655        )
6656    raise ValueError(f"Cannot convert {value}")

Convert a python value into an expression object.

Raises an error if a conversion is not possible.

Arguments:
  • value: A python object.
  • copy: Whether or not to copy value (only applies to Expressions and collections).
Returns:

Expression: the equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
6659def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6660    """
6661    Replace children of an expression with the result of a lambda fun(child) -> exp.
6662    """
6663    for k, v in expression.args.items():
6664        is_list_arg = type(v) is list
6665
6666        child_nodes = v if is_list_arg else [v]
6667        new_child_nodes = []
6668
6669        for cn in child_nodes:
6670            if isinstance(cn, Expression):
6671                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6672                    new_child_nodes.append(child_node)
6673                    child_node.parent = expression
6674                    child_node.arg_key = k
6675            else:
6676                new_child_nodes.append(cn)
6677
6678        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)

Replace children of an expression with the result of a lambda fun(child) -> exp.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
6681def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6682    """
6683    Return all table names referenced through columns in an expression.
6684
6685    Example:
6686        >>> import sqlglot
6687        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6688        ['a', 'c']
6689
6690    Args:
6691        expression: expression to find table names.
6692        exclude: a table name to exclude
6693
6694    Returns:
6695        A list of unique names.
6696    """
6697    return {
6698        table
6699        for table in (column.table for column in expression.find_all(Column))
6700        if table and table != exclude
6701    }

Return all table names referenced through columns in an expression.

Example:
>>> import sqlglot
>>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
['a', 'c']
Arguments:
  • expression: expression to find table names.
  • exclude: a table name to exclude
Returns:

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
6704def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6705    """Get the full name of a table as a string.
6706
6707    Args:
6708        table: Table expression node or string.
6709        dialect: The dialect to generate the table name for.
6710        identify: Determines when an identifier should be quoted. Possible values are:
6711            False (default): Never quote, except in cases where it's mandatory by the dialect.
6712            True: Always quote.
6713
6714    Examples:
6715        >>> from sqlglot import exp, parse_one
6716        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6717        'a.b.c'
6718
6719    Returns:
6720        The table name.
6721    """
6722
6723    table = maybe_parse(table, into=Table, dialect=dialect)
6724
6725    if not table:
6726        raise ValueError(f"Cannot parse {table}")
6727
6728    return ".".join(
6729        (
6730            part.sql(dialect=dialect, identify=True, copy=False)
6731            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6732            else part.name
6733        )
6734        for part in table.parts
6735    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
6738def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6739    """Returns a case normalized table name without quotes.
6740
6741    Args:
6742        table: the table to normalize
6743        dialect: the dialect to use for normalization rules
6744        copy: whether or not to copy the expression.
6745
6746    Examples:
6747        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6748        'A-B.c'
6749    """
6750    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6751
6752    return ".".join(
6753        p.name
6754        for p in normalize_identifiers(
6755            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6756        ).parts
6757    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether or not to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
6760def replace_tables(
6761    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6762) -> E:
6763    """Replace all tables in expression according to the mapping.
6764
6765    Args:
6766        expression: expression node to be transformed and replaced.
6767        mapping: mapping of table names.
6768        dialect: the dialect of the mapping table
6769        copy: whether or not to copy the expression.
6770
6771    Examples:
6772        >>> from sqlglot import exp, parse_one
6773        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6774        'SELECT * FROM c /* a.b */'
6775
6776    Returns:
6777        The mapped expression.
6778    """
6779
6780    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6781
6782    def _replace_tables(node: Expression) -> Expression:
6783        if isinstance(node, Table):
6784            original = normalize_table_name(node, dialect=dialect)
6785            new_name = mapping.get(original)
6786
6787            if new_name:
6788                table = to_table(
6789                    new_name,
6790                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6791                )
6792                table.add_comments([original])
6793                return table
6794        return node
6795
6796    return expression.transform(_replace_tables, copy=copy)

Replace all tables in expression according to the mapping.

Arguments:
  • expression: expression node to be transformed and replaced.
  • mapping: mapping of table names.
  • dialect: the dialect of the mapping table
  • copy: whether or not to copy the expression.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
'SELECT * FROM c /* a.b */'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
6799def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6800    """Replace placeholders in an expression.
6801
6802    Args:
6803        expression: expression node to be transformed and replaced.
6804        args: positional names that will substitute unnamed placeholders in the given order.
6805        kwargs: keyword arguments that will substitute named placeholders.
6806
6807    Examples:
6808        >>> from sqlglot import exp, parse_one
6809        >>> replace_placeholders(
6810        ...     parse_one("select * from :tbl where ? = ?"),
6811        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6812        ... ).sql()
6813        "SELECT * FROM foo WHERE str_col = 'b'"
6814
6815    Returns:
6816        The mapped expression.
6817    """
6818
6819    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6820        if isinstance(node, Placeholder):
6821            if node.name:
6822                new_name = kwargs.get(node.name)
6823                if new_name:
6824                    return convert(new_name)
6825            else:
6826                try:
6827                    return convert(next(args))
6828                except StopIteration:
6829                    pass
6830        return node
6831
6832    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Subqueryable], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
6835def expand(
6836    expression: Expression,
6837    sources: t.Dict[str, Subqueryable],
6838    dialect: DialectType = None,
6839    copy: bool = True,
6840) -> Expression:
6841    """Transforms an expression by expanding all referenced sources into subqueries.
6842
6843    Examples:
6844        >>> from sqlglot import parse_one
6845        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6846        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6847
6848        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6849        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6850
6851    Args:
6852        expression: The expression to expand.
6853        sources: A dictionary of name to Subqueryables.
6854        dialect: The dialect of the sources dict.
6855        copy: Whether or not to copy the expression during transformation. Defaults to True.
6856
6857    Returns:
6858        The transformed expression.
6859    """
6860    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6861
6862    def _expand(node: Expression):
6863        if isinstance(node, Table):
6864            name = normalize_table_name(node, dialect=dialect)
6865            source = sources.get(name)
6866            if source:
6867                subquery = source.subquery(node.alias or name)
6868                subquery.comments = [f"source: {name}"]
6869                return subquery.transform(_expand, copy=False)
6870        return node
6871
6872    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dictionary of name to Subqueryables.
  • dialect: The dialect of the sources dict.
  • copy: Whether or not to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
6875def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6876    """
6877    Returns a Func expression.
6878
6879    Examples:
6880        >>> func("abs", 5).sql()
6881        'ABS(5)'
6882
6883        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6884        'CAST(5 AS DOUBLE)'
6885
6886    Args:
6887        name: the name of the function to build.
6888        args: the args used to instantiate the function of interest.
6889        copy: whether or not to copy the argument expressions.
6890        dialect: the source dialect.
6891        kwargs: the kwargs used to instantiate the function of interest.
6892
6893    Note:
6894        The arguments `args` and `kwargs` are mutually exclusive.
6895
6896    Returns:
6897        An instance of the function of interest, or an anonymous function, if `name` doesn't
6898        correspond to an existing `sqlglot.expressions.Func` class.
6899    """
6900    if args and kwargs:
6901        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6902
6903    from sqlglot.dialects.dialect import Dialect
6904
6905    dialect = Dialect.get_or_raise(dialect)
6906
6907    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6908    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6909
6910    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6911    if constructor:
6912        if converted:
6913            if "dialect" in constructor.__code__.co_varnames:
6914                function = constructor(converted, dialect=dialect)
6915            else:
6916                function = constructor(converted)
6917        elif constructor.__name__ == "from_arg_list":
6918            function = constructor.__self__(**kwargs)  # type: ignore
6919        else:
6920            constructor = FUNCTION_BY_NAME.get(name.upper())
6921            if constructor:
6922                function = constructor(**kwargs)
6923            else:
6924                raise ValueError(
6925                    f"Unable to convert '{name}' into a Func. Either manually construct "
6926                    "the Func expression of interest or parse the function call."
6927                )
6928    else:
6929        kwargs = kwargs or {"expressions": converted}
6930        function = Anonymous(this=name, **kwargs)
6931
6932    for error_message in function.error_messages(converted):
6933        raise ValueError(error_message)
6934
6935    return function

Returns a Func expression.

Examples:
>>> func("abs", 5).sql()
'ABS(5)'
>>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
'CAST(5 AS DOUBLE)'
Arguments:
  • name: the name of the function to build.
  • args: the args used to instantiate the function of interest.
  • copy: whether or not to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Note:

The arguments args and kwargs are mutually exclusive.

Returns:

An instance of the function of interest, or an anonymous function, if name doesn't correspond to an existing Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
6938def case(
6939    expression: t.Optional[ExpOrStr] = None,
6940    **opts,
6941) -> Case:
6942    """
6943    Initialize a CASE statement.
6944
6945    Example:
6946        case().when("a = 1", "foo").else_("bar")
6947
6948    Args:
6949        expression: Optionally, the input expression (not all dialects support this)
6950        **opts: Extra keyword arguments for parsing `expression`
6951    """
6952    if expression is not None:
6953        this = maybe_parse(expression, **opts)
6954    else:
6955        this = None
6956    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def cast_unless( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], *types: Union[str, DataType, DataType.Type], **opts: Any) -> Expression | Cast:
6959def cast_unless(
6960    expression: ExpOrStr,
6961    to: DATA_TYPE,
6962    *types: DATA_TYPE,
6963    **opts: t.Any,
6964) -> Expression | Cast:
6965    """
6966    Cast an expression to a data type unless it is a specified type.
6967
6968    Args:
6969        expression: The expression to cast.
6970        to: The data type to cast to.
6971        **types: The types to exclude from casting.
6972        **opts: Extra keyword arguments for parsing `expression`
6973    """
6974    expr = maybe_parse(expression, **opts)
6975    if expr.is_type(*types):
6976        return expr
6977    return cast(expr, to, **opts)

Cast an expression to a data type unless it is a specified type.

Arguments:
  • expression: The expression to cast.
  • to: The data type to cast to.
  • **types: The types to exclude from casting.
  • **opts: Extra keyword arguments for parsing expression
def true() -> Boolean:
6980def true() -> Boolean:
6981    """
6982    Returns a true Boolean expression.
6983    """
6984    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6987def false() -> Boolean:
6988    """
6989    Returns a false Boolean expression.
6990    """
6991    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6994def null() -> Null:
6995    """
6996    Returns a Null expression.
6997    """
6998    return Null()

Returns a Null expression.