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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
147    def text(self, key) -> str:
148        """
149        Returns a textual representation of the argument corresponding to "key". This can only be used
150        for args that are strings or leaf Expression instances, such as identifiers and literals.
151        """
152        field = self.args.get(key)
153        if isinstance(field, str):
154            return field
155        if isinstance(field, (Identifier, Literal, Var)):
156            return field.this
157        if isinstance(field, (Star, Null)):
158            return field.name
159        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
161    @property
162    def is_string(self) -> bool:
163        """
164        Checks whether a Literal expression is a string.
165        """
166        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

is_int: bool
175    @property
176    def is_int(self) -> bool:
177        """
178        Checks whether a Literal expression is an integer.
179        """
180        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
182    @property
183    def is_star(self) -> bool:
184        """Checks whether an expression is a star."""
185        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
196    @property
197    def alias_column_names(self) -> t.List[str]:
198        table_alias = self.args.get("alias")
199        if not table_alias:
200            return []
201        return [c.name for c in table_alias.args.get("columns") or []]
name: str
203    @property
204    def name(self) -> str:
205        return self.text("this")
alias_or_name: str
207    @property
208    def alias_or_name(self) -> str:
209        return self.alias or self.name
output_name: str
211    @property
212    def output_name(self) -> str:
213        """
214        Name of the output column if this expression is a selection.
215
216        If the Expression has no output name, an empty string is returned.
217
218        Example:
219            >>> from sqlglot import parse_one
220            >>> parse_one("SELECT a").expressions[0].output_name
221            'a'
222            >>> parse_one("SELECT b AS c").expressions[0].output_name
223            'c'
224            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
225            ''
226        """
227        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]
229    @property
230    def type(self) -> t.Optional[DataType]:
231        return self._type
def is_type(self, *dtypes) -> bool:
239    def is_type(self, *dtypes) -> bool:
240        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
242    def is_leaf(self) -> bool:
243        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
245    @property
246    def meta(self) -> t.Dict[str, t.Any]:
247        if self._meta is None:
248            self._meta = {}
249        return self._meta
def copy(self):
264    def copy(self):
265        """
266        Returns a deep copy of the expression.
267        """
268        new = deepcopy(self)
269        new.parent = self.parent
270        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
272    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
273        if self.comments is None:
274            self.comments = []
275        if comments:
276            for comment in comments:
277                _, *meta = comment.split(SQLGLOT_META)
278                if meta:
279                    for kv in "".join(meta).split(","):
280                        k, *v = kv.split("=")
281                        value = v[0].strip() if v else True
282                        self.meta[k.strip()] = value
283                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
285    def append(self, arg_key: str, value: t.Any) -> None:
286        """
287        Appends value to arg_key if it's a list or sets it as a new list.
288
289        Args:
290            arg_key (str): name of the list expression arg
291            value (Any): value to append to the list
292        """
293        if not isinstance(self.args.get(arg_key), list):
294            self.args[arg_key] = []
295        self.args[arg_key].append(value)
296        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:
298    def set(self, arg_key: str, value: t.Any) -> None:
299        """
300        Sets arg_key to value.
301
302        Args:
303            arg_key: name of the expression arg.
304            value: value to set the arg to.
305        """
306        if value is None:
307            self.args.pop(arg_key, None)
308            return
309
310        self.args[arg_key] = value
311        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
323    @property
324    def depth(self) -> int:
325        """
326        Returns the depth of this tree.
327        """
328        if self.parent:
329            return self.parent.depth + 1
330        return 0

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
332    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
333        """Yields the key and expression for all arguments, exploding list args."""
334        for k, vs in self.args.items():
335            if type(vs) is list:
336                for v in vs:
337                    if hasattr(v, "parent"):
338                        yield k, v
339            else:
340                if hasattr(vs, "parent"):
341                    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]:
343    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
344        """
345        Returns the first node in this tree which matches at least one of
346        the specified types.
347
348        Args:
349            expression_types: the expression type(s) to match.
350            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
351
352        Returns:
353            The node which matches the criteria or None if no such node was found.
354        """
355        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]:
357    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
358        """
359        Returns a generator object which visits all nodes in this tree and only
360        yields those that match at least one of the specified expression types.
361
362        Args:
363            expression_types: the expression type(s) to match.
364            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
365
366        Returns:
367            The generator object.
368        """
369        for expression, *_ in self.walk(bfs=bfs):
370            if isinstance(expression, expression_types):
371                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]:
373    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
374        """
375        Returns a nearest parent matching expression_types.
376
377        Args:
378            expression_types: the expression type(s) to match.
379
380        Returns:
381            The parent node.
382        """
383        ancestor = self.parent
384        while ancestor and not isinstance(ancestor, expression_types):
385            ancestor = ancestor.parent
386        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]
388    @property
389    def parent_select(self) -> t.Optional[Select]:
390        """
391        Returns the parent select statement.
392        """
393        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
395    @property
396    def same_parent(self) -> bool:
397        """Returns if the parent is the same class as itself."""
398        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
400    def root(self) -> Expression:
401        """
402        Returns the root expression of this tree.
403        """
404        expression = self
405        while expression.parent:
406            expression = expression.parent
407        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
409    def walk(self, bfs=True, prune=None):
410        """
411        Returns a generator object which visits all nodes in this tree.
412
413        Args:
414            bfs (bool): if set to True the BFS traversal order will be applied,
415                otherwise the DFS traversal will be used instead.
416            prune ((node, parent, arg_key) -> bool): callable that returns True if
417                the generator should stop traversing this branch of the tree.
418
419        Returns:
420            the generator object.
421        """
422        if bfs:
423            yield from self.bfs(prune=prune)
424        else:
425            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):
427    def dfs(self, parent=None, key=None, prune=None):
428        """
429        Returns a generator object which visits all nodes in this tree in
430        the DFS (Depth-first) order.
431
432        Returns:
433            The generator object.
434        """
435        parent = parent or self.parent
436        yield self, parent, key
437        if prune and prune(self, parent, key):
438            return
439
440        for k, v in self.iter_expressions():
441            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):
443    def bfs(self, prune=None):
444        """
445        Returns a generator object which visits all nodes in this tree in
446        the BFS (Breadth-first) order.
447
448        Returns:
449            The generator object.
450        """
451        queue = deque([(self, self.parent, None)])
452
453        while queue:
454            item, parent, key = queue.popleft()
455
456            yield item, parent, key
457            if prune and prune(item, parent, key):
458                continue
459
460            for k, v in item.iter_expressions():
461                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):
463    def unnest(self):
464        """
465        Returns the first non parenthesis child or self.
466        """
467        expression = self
468        while type(expression) is Paren:
469            expression = expression.this
470        return expression

Returns the first non parenthesis child or self.

def unalias(self):
472    def unalias(self):
473        """
474        Returns the inner expression if this is an Alias.
475        """
476        if isinstance(self, Alias):
477            return self.this
478        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
480    def unnest_operands(self):
481        """
482        Returns unnested operands as a tuple.
483        """
484        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
486    def flatten(self, unnest=True):
487        """
488        Returns a generator which yields child nodes whose parents are the same class.
489
490        A AND B AND C -> [A, B, C]
491        """
492        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and type(n) is not self.__class__):
493            if type(node) is not self.__class__:
494                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:
502    def to_s(self) -> str:
503        """
504        Same as __repr__, but includes additional information which can be useful
505        for debugging, like empty or missing args and the AST nodes' object IDs.
506        """
507        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:
509    def sql(self, dialect: DialectType = None, **opts) -> str:
510        """
511        Returns SQL string representation of this tree.
512
513        Args:
514            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
515            opts: other `sqlglot.generator.Generator` options.
516
517        Returns:
518            The SQL string.
519        """
520        from sqlglot.dialects import Dialect
521
522        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):
524    def transform(self, fun, *args, copy=True, **kwargs):
525        """
526        Recursively visits all tree nodes (excluding already transformed ones)
527        and applies the given transformation function to each node.
528
529        Args:
530            fun (function): a function which takes a node as an argument and returns a
531                new transformed node or the same node without modifications. If the function
532                returns None, then the corresponding node will be removed from the syntax tree.
533            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
534                modified in place.
535
536        Returns:
537            The transformed tree.
538        """
539        node = self.copy() if copy else self
540        new_node = fun(node, *args, **kwargs)
541
542        if new_node is None or not isinstance(new_node, Expression):
543            return new_node
544        if new_node is not node:
545            new_node.parent = node.parent
546            return new_node
547
548        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
549        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):
559    def replace(self, expression):
560        """
561        Swap out this expression with a new expression.
562
563        For example::
564
565            >>> tree = Select().select("x").from_("tbl")
566            >>> tree.find(Column).replace(column("y"))
567            Column(
568              this=Identifier(this=y, quoted=False))
569            >>> tree.sql()
570            'SELECT y FROM tbl'
571
572        Args:
573            expression: new node
574
575        Returns:
576            The new expression or expressions.
577        """
578        if not self.parent:
579            return expression
580
581        parent = self.parent
582        self.parent = None
583
584        replace_children(parent, lambda child: expression if child is self else child)
585        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:
587    def pop(self: E) -> E:
588        """
589        Remove this expression from its AST.
590
591        Returns:
592            The popped expression.
593        """
594        self.replace(None)
595        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
597    def assert_is(self, type_: t.Type[E]) -> E:
598        """
599        Assert that this `Expression` is an instance of `type_`.
600
601        If it is NOT an instance of `type_`, this raises an assertion error.
602        Otherwise, this returns this expression.
603
604        Examples:
605            This is useful for type security in chained expressions:
606
607            >>> import sqlglot
608            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
609            'SELECT x, z FROM y'
610        """
611        if not isinstance(self, type_):
612            raise AssertionError(f"{self} is not {type_}.")
613        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]:
615    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
616        """
617        Checks if this expression is valid (e.g. all mandatory args are set).
618
619        Args:
620            args: a sequence of values that were used to instantiate a Func expression. This is used
621                to check that the provided arguments don't exceed the function argument limit.
622
623        Returns:
624            A list of error messages for all possible errors that were found.
625        """
626        errors: t.List[str] = []
627
628        for k in self.args:
629            if k not in self.arg_types:
630                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
631        for k, mandatory in self.arg_types.items():
632            v = self.args.get(k)
633            if mandatory and (v is None or (isinstance(v, list) and not v)):
634                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
635
636        if (
637            args
638            and isinstance(self, Func)
639            and len(args) > len(self.arg_types)
640            and not self.is_var_len_args
641        ):
642            errors.append(
643                f"The number of provided arguments ({len(args)}) is greater than "
644                f"the maximum number of supported arguments ({len(self.arg_types)})"
645            )
646
647        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):
649    def dump(self):
650        """
651        Dump this Expression to a JSON-serializable dict.
652        """
653        from sqlglot.serde import dump
654
655        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
657    @classmethod
658    def load(cls, obj):
659        """
660        Load a dict (as returned by `Expression.dump`) into an Expression instance.
661        """
662        from sqlglot.serde import load
663
664        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:
666    def and_(
667        self,
668        *expressions: t.Optional[ExpOrStr],
669        dialect: DialectType = None,
670        copy: bool = True,
671        **opts,
672    ) -> Condition:
673        """
674        AND this condition with one or multiple expressions.
675
676        Example:
677            >>> condition("x=1").and_("y=1").sql()
678            'x = 1 AND y = 1'
679
680        Args:
681            *expressions: the SQL code strings to parse.
682                If an `Expression` instance is passed, it will be used as-is.
683            dialect: the dialect used to parse the input expression.
684            copy: whether or not to copy the involved expressions (only applies to Expressions).
685            opts: other options to use to parse the input expressions.
686
687        Returns:
688            The new And condition.
689        """
690        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:
692    def or_(
693        self,
694        *expressions: t.Optional[ExpOrStr],
695        dialect: DialectType = None,
696        copy: bool = True,
697        **opts,
698    ) -> Condition:
699        """
700        OR this condition with one or multiple expressions.
701
702        Example:
703            >>> condition("x=1").or_("y=1").sql()
704            'x = 1 OR y = 1'
705
706        Args:
707            *expressions: the SQL code strings to parse.
708                If an `Expression` instance is passed, it will be used as-is.
709            dialect: the dialect used to parse the input expression.
710            copy: whether or not to copy the involved expressions (only applies to Expressions).
711            opts: other options to use to parse the input expressions.
712
713        Returns:
714            The new Or condition.
715        """
716        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):
718    def not_(self, copy: bool = True):
719        """
720        Wrap this condition with NOT.
721
722        Example:
723            >>> condition("x=1").not_().sql()
724            'NOT x = 1'
725
726        Args:
727            copy: whether or not to copy this object.
728
729        Returns:
730            The new Not instance.
731        """
732        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:
734    def as_(
735        self,
736        alias: str | Identifier,
737        quoted: t.Optional[bool] = None,
738        dialect: DialectType = None,
739        copy: bool = True,
740        **opts,
741    ) -> Alias:
742        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:
767    def isin(
768        self,
769        *expressions: t.Any,
770        query: t.Optional[ExpOrStr] = None,
771        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
772        copy: bool = True,
773        **opts,
774    ) -> In:
775        return In(
776            this=maybe_copy(self, copy),
777            expressions=[convert(e, copy=copy) for e in expressions],
778            query=maybe_parse(query, copy=copy, **opts) if query else None,
779            unnest=(
780                Unnest(
781                    expressions=[
782                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
783                        for e in ensure_list(unnest)
784                    ]
785                )
786                if unnest
787                else None
788            ),
789        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
791    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
792        return Between(
793            this=maybe_copy(self, copy),
794            low=convert(low, copy=copy, **opts),
795            high=convert(high, copy=copy, **opts),
796        )
def is_( self, other: Union[str, Expression]) -> Is:
798    def is_(self, other: ExpOrStr) -> Is:
799        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
801    def like(self, other: ExpOrStr) -> Like:
802        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
804    def ilike(self, other: ExpOrStr) -> ILike:
805        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
807    def eq(self, other: t.Any) -> EQ:
808        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
810    def neq(self, other: t.Any) -> NEQ:
811        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
813    def rlike(self, other: ExpOrStr) -> RegexpLike:
814        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
816    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
817        div = self._binop(Div, other)
818        div.args["typed"] = typed
819        div.args["safe"] = safe
820        return div
def desc(self, nulls_first: bool = False) -> Ordered:
822    def desc(self, nulls_first: bool = False) -> Ordered:
823        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):
906class Condition(Expression):
907    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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):
1077class Create(DDL):
1078    arg_types = {
1079        "with": False,
1080        "this": True,
1081        "kind": True,
1082        "expression": False,
1083        "exists": False,
1084        "properties": False,
1085        "replace": False,
1086        "unique": False,
1087        "indexes": False,
1088        "no_schema_binding": False,
1089        "begin": False,
1090        "end": False,
1091        "clone": False,
1092    }
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):
1098class Clone(Expression):
1099    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1102class Describe(Expression):
1103    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):
1106class Kill(Expression):
1107    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1110class Pragma(Expression):
1111    pass
key = 'pragma'
class Set(Expression):
1114class Set(Expression):
1115    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1118class Heredoc(Expression):
1119    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1122class SetItem(Expression):
1123    arg_types = {
1124        "this": False,
1125        "expressions": False,
1126        "kind": False,
1127        "collate": False,  # MySQL SET NAMES statement
1128        "global": False,
1129    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1132class Show(Expression):
1133    arg_types = {
1134        "this": True,
1135        "history": False,
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    }
arg_types = {'this': True, 'history': False, '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):
1158class UserDefinedFunction(Expression):
1159    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1162class CharacterSet(Expression):
1163    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
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"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1169    @property
1170    def recursive(self) -> bool:
1171        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1174class WithinGroup(Expression):
1175    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1180class CTE(DerivedTable):
1181    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1184class TableAlias(Expression):
1185    arg_types = {"this": False, "columns": False}
1186
1187    @property
1188    def columns(self):
1189        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1187    @property
1188    def columns(self):
1189        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1192class BitString(Condition):
1193    pass
key = 'bitstring'
class HexString(Condition):
1196class HexString(Condition):
1197    pass
key = 'hexstring'
class ByteString(Condition):
1200class ByteString(Condition):
1201    pass
key = 'bytestring'
class RawString(Condition):
1204class RawString(Condition):
1205    pass
key = 'rawstring'
class UnicodeString(Condition):
1208class UnicodeString(Condition):
1209    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
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]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1215    @property
1216    def table(self) -> str:
1217        return self.text("table")
db: str
1219    @property
1220    def db(self) -> str:
1221        return self.text("db")
catalog: str
1223    @property
1224    def catalog(self) -> str:
1225        return self.text("catalog")
output_name: str
1227    @property
1228    def output_name(self) -> str:
1229        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]
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        ]

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

def to_dot(self) -> Dot | Identifier:
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]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1253class ColumnPosition(Expression):
1254    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
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 []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1266    @property
1267    def constraints(self) -> t.List[ColumnConstraint]:
1268        return self.args.get("constraints") or []
key = 'columndef'
class AlterColumn(Expression):
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    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1283class RenameColumn(Expression):
1284    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1287class RenameTable(Expression):
1288    pass
key = 'renametable'
class SwapTable(Expression):
1291class SwapTable(Expression):
1292    pass
key = 'swaptable'
class Comment(Expression):
1295class Comment(Expression):
1296    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):
1299class Comprehension(Expression):
1300    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):
1304class MergeTreeTTLAction(Expression):
1305    arg_types = {
1306        "this": True,
1307        "delete": False,
1308        "recompress": False,
1309        "to_disk": False,
1310        "to_volume": False,
1311    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1315class MergeTreeTTL(Expression):
1316    arg_types = {
1317        "expressions": True,
1318        "where": False,
1319        "group": False,
1320        "aggregates": False,
1321    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
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    }
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):
1337class ColumnConstraint(Expression):
1338    arg_types = {"this": False, "kind": True}
1339
1340    @property
1341    def kind(self) -> ColumnConstraintKind:
1342        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1340    @property
1341    def kind(self) -> ColumnConstraintKind:
1342        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1345class ColumnConstraintKind(Expression):
1346    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1349class AutoIncrementColumnConstraint(ColumnConstraintKind):
1350    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1353class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1354    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1357class CaseSpecificColumnConstraint(ColumnConstraintKind):
1358    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1361class CharacterSetColumnConstraint(ColumnConstraintKind):
1362    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1365class CheckColumnConstraint(ColumnConstraintKind):
1366    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1369class ClusteredColumnConstraint(ColumnConstraintKind):
1370    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1373class CollateColumnConstraint(ColumnConstraintKind):
1374    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1377class CommentColumnConstraint(ColumnConstraintKind):
1378    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1381class CompressColumnConstraint(ColumnConstraintKind):
1382    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1385class DateFormatColumnConstraint(ColumnConstraintKind):
1386    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1389class DefaultColumnConstraint(ColumnConstraintKind):
1390    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1393class EncodeColumnConstraint(ColumnConstraintKind):
1394    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
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    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1411class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1412    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1416class IndexColumnConstraint(ColumnConstraintKind):
1417    arg_types = {
1418        "this": False,
1419        "schema": True,
1420        "kind": False,
1421        "index_type": False,
1422        "options": False,
1423    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1426class InlineLengthColumnConstraint(ColumnConstraintKind):
1427    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1430class NonClusteredColumnConstraint(ColumnConstraintKind):
1431    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1434class NotForReplicationColumnConstraint(ColumnConstraintKind):
1435    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1438class NotNullColumnConstraint(ColumnConstraintKind):
1439    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1443class OnUpdateColumnConstraint(ColumnConstraintKind):
1444    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1448class TransformColumnConstraint(ColumnConstraintKind):
1449    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1452class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1453    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1456class TitleColumnConstraint(ColumnConstraintKind):
1457    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1460class UniqueColumnConstraint(ColumnConstraintKind):
1461    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1464class UppercaseColumnConstraint(ColumnConstraintKind):
1465    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1468class PathColumnConstraint(ColumnConstraintKind):
1469    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1474class ComputedColumnConstraint(ColumnConstraintKind):
1475    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1478class Constraint(Expression):
1479    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
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        )
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:
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        )

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

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):
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    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1579class Filter(Expression):
1580    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1583class Check(Expression):
1584    pass
key = 'check'
class Connect(Expression):
1588class Connect(Expression):
1589    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1592class Prior(Expression):
1593    pass
key = 'prior'
class Directory(Expression):
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}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1601class ForeignKey(Expression):
1602    arg_types = {
1603        "expressions": True,
1604        "reference": False,
1605        "delete": False,
1606        "update": False,
1607    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1610class ColumnPrefix(Expression):
1611    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1614class PrimaryKey(Expression):
1615    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1620class Into(Expression):
1621    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
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
name: str
1625    @property
1626    def name(self) -> str:
1627        return self.this.name
alias_or_name: str
1629    @property
1630    def alias_or_name(self) -> str:
1631        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1634class Having(Expression):
1635    pass
key = 'having'
class Hint(Expression):
1638class Hint(Expression):
1639    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1642class JoinHint(Expression):
1643    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
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
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1649    @property
1650    def quoted(self) -> bool:
1651        return bool(self.args.get("quoted"))
hashable_args: Any
1653    @property
1654    def hashable_args(self) -> t.Any:
1655        return (self.this, self.quoted)
output_name: str
1657    @property
1658    def output_name(self) -> str:
1659        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):
1663class Opclass(Expression):
1664    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
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    }
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):
1682class Insert(DDL, DML):
1683    arg_types = {
1684        "with": False,
1685        "this": True,
1686        "expression": False,
1687        "conflict": False,
1688        "returning": False,
1689        "overwrite": False,
1690        "exists": False,
1691        "partition": False,
1692        "alternative": False,
1693        "where": False,
1694        "ignore": False,
1695        "by_name": False,
1696    }
1697
1698    def with_(
1699        self,
1700        alias: ExpOrStr,
1701        as_: ExpOrStr,
1702        recursive: t.Optional[bool] = None,
1703        append: bool = True,
1704        dialect: DialectType = None,
1705        copy: bool = True,
1706        **opts,
1707    ) -> Insert:
1708        """
1709        Append to or set the common table expressions.
1710
1711        Example:
1712            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1713            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1714
1715        Args:
1716            alias: the SQL code string to parse as the table name.
1717                If an `Expression` instance is passed, this is used as-is.
1718            as_: the SQL code string to parse as the table expression.
1719                If an `Expression` instance is passed, it will be used as-is.
1720            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1721            append: if `True`, add to any existing expressions.
1722                Otherwise, this resets the expressions.
1723            dialect: the dialect used to parse the input expression.
1724            copy: if `False`, modify this expression instance in-place.
1725            opts: other options to use to parse the input expressions.
1726
1727        Returns:
1728            The modified expression.
1729        """
1730        return _apply_cte_builder(
1731            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1732        )
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:
1698    def with_(
1699        self,
1700        alias: ExpOrStr,
1701        as_: ExpOrStr,
1702        recursive: t.Optional[bool] = None,
1703        append: bool = True,
1704        dialect: DialectType = None,
1705        copy: bool = True,
1706        **opts,
1707    ) -> Insert:
1708        """
1709        Append to or set the common table expressions.
1710
1711        Example:
1712            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1713            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1714
1715        Args:
1716            alias: the SQL code string to parse as the table name.
1717                If an `Expression` instance is passed, this is used as-is.
1718            as_: the SQL code string to parse as the table expression.
1719                If an `Expression` instance is passed, it will be used as-is.
1720            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1721            append: if `True`, add to any existing expressions.
1722                Otherwise, this resets the expressions.
1723            dialect: the dialect used to parse the input expression.
1724            copy: if `False`, modify this expression instance in-place.
1725            opts: other options to use to parse the input expressions.
1726
1727        Returns:
1728            The modified expression.
1729        """
1730        return _apply_cte_builder(
1731            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1732        )

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):
1735class OnConflict(Expression):
1736    arg_types = {
1737        "duplicate": False,
1738        "expressions": False,
1739        "nothing": False,
1740        "key": False,
1741        "constraint": False,
1742    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1745class Returning(Expression):
1746    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1750class Introducer(Expression):
1751    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1755class National(Expression):
1756    pass
key = 'national'
class LoadData(Expression):
1759class LoadData(Expression):
1760    arg_types = {
1761        "this": True,
1762        "local": False,
1763        "overwrite": False,
1764        "inpath": True,
1765        "partition": False,
1766        "input_format": False,
1767        "serde": False,
1768    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1771class Partition(Expression):
1772    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1775class Fetch(Expression):
1776    arg_types = {
1777        "direction": False,
1778        "count": False,
1779        "percent": False,
1780        "with_ties": False,
1781    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1784class Group(Expression):
1785    arg_types = {
1786        "expressions": False,
1787        "grouping_sets": False,
1788        "cube": False,
1789        "rollup": False,
1790        "totals": False,
1791        "all": False,
1792    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1795class Lambda(Expression):
1796    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1799class Limit(Expression):
1800    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
1803class Literal(Condition):
1804    arg_types = {"this": True, "is_string": True}
1805
1806    @property
1807    def hashable_args(self) -> t.Any:
1808        return (self.this, self.args.get("is_string"))
1809
1810    @classmethod
1811    def number(cls, number) -> Literal:
1812        return cls(this=str(number), is_string=False)
1813
1814    @classmethod
1815    def string(cls, string) -> Literal:
1816        return cls(this=str(string), is_string=True)
1817
1818    @property
1819    def output_name(self) -> str:
1820        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1806    @property
1807    def hashable_args(self) -> t.Any:
1808        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1810    @classmethod
1811    def number(cls, number) -> Literal:
1812        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1814    @classmethod
1815    def string(cls, string) -> Literal:
1816        return cls(this=str(string), is_string=True)
output_name: str
1818    @property
1819    def output_name(self) -> str:
1820        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):
1823class Join(Expression):
1824    arg_types = {
1825        "this": True,
1826        "on": False,
1827        "side": False,
1828        "kind": False,
1829        "using": False,
1830        "method": False,
1831        "global": False,
1832        "hint": False,
1833    }
1834
1835    @property
1836    def method(self) -> str:
1837        return self.text("method").upper()
1838
1839    @property
1840    def kind(self) -> str:
1841        return self.text("kind").upper()
1842
1843    @property
1844    def side(self) -> str:
1845        return self.text("side").upper()
1846
1847    @property
1848    def hint(self) -> str:
1849        return self.text("hint").upper()
1850
1851    @property
1852    def alias_or_name(self) -> str:
1853        return self.this.alias_or_name
1854
1855    def on(
1856        self,
1857        *expressions: t.Optional[ExpOrStr],
1858        append: bool = True,
1859        dialect: DialectType = None,
1860        copy: bool = True,
1861        **opts,
1862    ) -> Join:
1863        """
1864        Append to or set the ON expressions.
1865
1866        Example:
1867            >>> import sqlglot
1868            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1869            'JOIN x ON y = 1'
1870
1871        Args:
1872            *expressions: the SQL code strings to parse.
1873                If an `Expression` instance is passed, it will be used as-is.
1874                Multiple expressions are combined with an AND operator.
1875            append: if `True`, AND the new expressions to any existing expression.
1876                Otherwise, this resets the expression.
1877            dialect: the dialect used to parse the input expressions.
1878            copy: if `False`, modify this expression instance in-place.
1879            opts: other options to use to parse the input expressions.
1880
1881        Returns:
1882            The modified Join expression.
1883        """
1884        join = _apply_conjunction_builder(
1885            *expressions,
1886            instance=self,
1887            arg="on",
1888            append=append,
1889            dialect=dialect,
1890            copy=copy,
1891            **opts,
1892        )
1893
1894        if join.kind == "CROSS":
1895            join.set("kind", None)
1896
1897        return join
1898
1899    def using(
1900        self,
1901        *expressions: t.Optional[ExpOrStr],
1902        append: bool = True,
1903        dialect: DialectType = None,
1904        copy: bool = True,
1905        **opts,
1906    ) -> Join:
1907        """
1908        Append to or set the USING expressions.
1909
1910        Example:
1911            >>> import sqlglot
1912            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1913            'JOIN x USING (foo, bla)'
1914
1915        Args:
1916            *expressions: the SQL code strings to parse.
1917                If an `Expression` instance is passed, it will be used as-is.
1918            append: if `True`, concatenate the new expressions to the existing "using" list.
1919                Otherwise, this resets the expression.
1920            dialect: the dialect used to parse the input expressions.
1921            copy: if `False`, modify this expression instance in-place.
1922            opts: other options to use to parse the input expressions.
1923
1924        Returns:
1925            The modified Join expression.
1926        """
1927        join = _apply_list_builder(
1928            *expressions,
1929            instance=self,
1930            arg="using",
1931            append=append,
1932            dialect=dialect,
1933            copy=copy,
1934            **opts,
1935        )
1936
1937        if join.kind == "CROSS":
1938            join.set("kind", None)
1939
1940        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1835    @property
1836    def method(self) -> str:
1837        return self.text("method").upper()
kind: str
1839    @property
1840    def kind(self) -> str:
1841        return self.text("kind").upper()
side: str
1843    @property
1844    def side(self) -> str:
1845        return self.text("side").upper()
hint: str
1847    @property
1848    def hint(self) -> str:
1849        return self.text("hint").upper()
alias_or_name: str
1851    @property
1852    def alias_or_name(self) -> str:
1853        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:
1855    def on(
1856        self,
1857        *expressions: t.Optional[ExpOrStr],
1858        append: bool = True,
1859        dialect: DialectType = None,
1860        copy: bool = True,
1861        **opts,
1862    ) -> Join:
1863        """
1864        Append to or set the ON expressions.
1865
1866        Example:
1867            >>> import sqlglot
1868            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1869            'JOIN x ON y = 1'
1870
1871        Args:
1872            *expressions: the SQL code strings to parse.
1873                If an `Expression` instance is passed, it will be used as-is.
1874                Multiple expressions are combined with an AND operator.
1875            append: if `True`, AND the new expressions to any existing expression.
1876                Otherwise, this resets the expression.
1877            dialect: the dialect used to parse the input expressions.
1878            copy: if `False`, modify this expression instance in-place.
1879            opts: other options to use to parse the input expressions.
1880
1881        Returns:
1882            The modified Join expression.
1883        """
1884        join = _apply_conjunction_builder(
1885            *expressions,
1886            instance=self,
1887            arg="on",
1888            append=append,
1889            dialect=dialect,
1890            copy=copy,
1891            **opts,
1892        )
1893
1894        if join.kind == "CROSS":
1895            join.set("kind", None)
1896
1897        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:
1899    def using(
1900        self,
1901        *expressions: t.Optional[ExpOrStr],
1902        append: bool = True,
1903        dialect: DialectType = None,
1904        copy: bool = True,
1905        **opts,
1906    ) -> Join:
1907        """
1908        Append to or set the USING expressions.
1909
1910        Example:
1911            >>> import sqlglot
1912            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1913            'JOIN x USING (foo, bla)'
1914
1915        Args:
1916            *expressions: the SQL code strings to parse.
1917                If an `Expression` instance is passed, it will be used as-is.
1918            append: if `True`, concatenate the new expressions to the existing "using" list.
1919                Otherwise, this resets the expression.
1920            dialect: the dialect used to parse the input expressions.
1921            copy: if `False`, modify this expression instance in-place.
1922            opts: other options to use to parse the input expressions.
1923
1924        Returns:
1925            The modified Join expression.
1926        """
1927        join = _apply_list_builder(
1928            *expressions,
1929            instance=self,
1930            arg="using",
1931            append=append,
1932            dialect=dialect,
1933            copy=copy,
1934            **opts,
1935        )
1936
1937        if join.kind == "CROSS":
1938            join.set("kind", None)
1939
1940        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):
1943class Lateral(UDTF):
1944    arg_types = {
1945        "this": True,
1946        "view": False,
1947        "outer": False,
1948        "alias": False,
1949        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1950    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
1953class MatchRecognize(Expression):
1954    arg_types = {
1955        "partition_by": False,
1956        "order": False,
1957        "measures": False,
1958        "rows": False,
1959        "after": False,
1960        "pattern": False,
1961        "define": False,
1962        "alias": False,
1963    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1968class Final(Expression):
1969    pass
key = 'final'
class Offset(Expression):
1972class Offset(Expression):
1973    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
1976class Order(Expression):
1977    arg_types = {
1978        "this": False,
1979        "expressions": True,
1980        "interpolate": False,
1981        "siblings": False,
1982    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
1986class WithFill(Expression):
1987    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
1992class Cluster(Order):
1993    pass
key = 'cluster'
class Distribute(Order):
1996class Distribute(Order):
1997    pass
key = 'distribute'
class Sort(Order):
2000class Sort(Order):
2001    pass
key = 'sort'
class Ordered(Expression):
2004class Ordered(Expression):
2005    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):
2008class Property(Expression):
2009    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2012class AlgorithmProperty(Property):
2013    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2016class AutoIncrementProperty(Property):
2017    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2021class AutoRefreshProperty(Property):
2022    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2025class BlockCompressionProperty(Property):
2026    arg_types = {
2027        "autotemp": False,
2028        "always": False,
2029        "default": False,
2030        "manual": False,
2031        "never": False,
2032    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2035class CharacterSetProperty(Property):
2036    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2039class ChecksumProperty(Property):
2040    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2043class CollateProperty(Property):
2044    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2047class CopyGrantsProperty(Property):
2048    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2051class DataBlocksizeProperty(Property):
2052    arg_types = {
2053        "size": False,
2054        "units": False,
2055        "minimum": False,
2056        "maximum": False,
2057        "default": False,
2058    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2061class DefinerProperty(Property):
2062    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2065class DistKeyProperty(Property):
2066    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2069class DistStyleProperty(Property):
2070    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2073class EngineProperty(Property):
2074    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2077class HeapProperty(Property):
2078    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2081class ToTableProperty(Property):
2082    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2085class ExecuteAsProperty(Property):
2086    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2089class ExternalProperty(Property):
2090    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2093class FallbackProperty(Property):
2094    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2097class FileFormatProperty(Property):
2098    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2101class FreespaceProperty(Property):
2102    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InheritsProperty(Property):
2105class InheritsProperty(Property):
2106    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2109class InputModelProperty(Property):
2110    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2113class OutputModelProperty(Property):
2114    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2117class IsolatedLoadingProperty(Property):
2118    arg_types = {
2119        "no": False,
2120        "concurrent": False,
2121        "for_all": False,
2122        "for_insert": False,
2123        "for_none": False,
2124    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2127class JournalProperty(Property):
2128    arg_types = {
2129        "no": False,
2130        "dual": False,
2131        "before": False,
2132        "local": False,
2133        "after": False,
2134    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2137class LanguageProperty(Property):
2138    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2142class ClusteredByProperty(Property):
2143    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2146class DictProperty(Property):
2147    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2150class DictSubProperty(Property):
2151    pass
key = 'dictsubproperty'
class DictRange(Property):
2154class DictRange(Property):
2155    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2160class OnCluster(Property):
2161    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2164class LikeProperty(Property):
2165    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2168class LocationProperty(Property):
2169    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2172class LockingProperty(Property):
2173    arg_types = {
2174        "this": False,
2175        "kind": True,
2176        "for_or_in": False,
2177        "lock_type": True,
2178        "override": False,
2179    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2182class LogProperty(Property):
2183    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2186class MaterializedProperty(Property):
2187    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2190class MergeBlockRatioProperty(Property):
2191    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):
2194class NoPrimaryIndexProperty(Property):
2195    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2198class OnProperty(Property):
2199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2202class OnCommitProperty(Property):
2203    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2206class PartitionedByProperty(Property):
2207    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2211class PartitionBoundSpec(Expression):
2212    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2213    arg_types = {
2214        "this": False,
2215        "expression": False,
2216        "from_expressions": False,
2217        "to_expressions": False,
2218    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2221class PartitionedOfProperty(Property):
2222    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2223    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2226class RemoteWithConnectionModelProperty(Property):
2227    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2230class ReturnsProperty(Property):
2231    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2234class RowFormatProperty(Property):
2235    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2238class RowFormatDelimitedProperty(Property):
2239    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2240    arg_types = {
2241        "fields": False,
2242        "escaped": False,
2243        "collection_items": False,
2244        "map_keys": False,
2245        "lines": False,
2246        "null": False,
2247        "serde": False,
2248    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2251class RowFormatSerdeProperty(Property):
2252    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2256class QueryTransform(Expression):
2257    arg_types = {
2258        "expressions": True,
2259        "command_script": True,
2260        "schema": False,
2261        "row_format_before": False,
2262        "record_writer": False,
2263        "row_format_after": False,
2264        "record_reader": False,
2265    }
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):
2268class SampleProperty(Property):
2269    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2272class SchemaCommentProperty(Property):
2273    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2276class SerdeProperties(Property):
2277    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2280class SetProperty(Property):
2281    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SetConfigProperty(Property):
2284class SetConfigProperty(Property):
2285    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2288class SettingsProperty(Property):
2289    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2292class SortKeyProperty(Property):
2293    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2296class SqlReadWriteProperty(Property):
2297    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2300class SqlSecurityProperty(Property):
2301    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2304class StabilityProperty(Property):
2305    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2308class TemporaryProperty(Property):
2309    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2312class TransformModelProperty(Property):
2313    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2316class TransientProperty(Property):
2317    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2320class VolatileProperty(Property):
2321    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2324class WithDataProperty(Property):
2325    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2328class WithJournalTableProperty(Property):
2329    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2332class WithSystemVersioningProperty(Property):
2333    # this -> history table name, expression -> data consistency check
2334    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2337class Properties(Expression):
2338    arg_types = {"expressions": True}
2339
2340    NAME_TO_PROPERTY = {
2341        "ALGORITHM": AlgorithmProperty,
2342        "AUTO_INCREMENT": AutoIncrementProperty,
2343        "CHARACTER SET": CharacterSetProperty,
2344        "CLUSTERED_BY": ClusteredByProperty,
2345        "COLLATE": CollateProperty,
2346        "COMMENT": SchemaCommentProperty,
2347        "DEFINER": DefinerProperty,
2348        "DISTKEY": DistKeyProperty,
2349        "DISTSTYLE": DistStyleProperty,
2350        "ENGINE": EngineProperty,
2351        "EXECUTE AS": ExecuteAsProperty,
2352        "FORMAT": FileFormatProperty,
2353        "LANGUAGE": LanguageProperty,
2354        "LOCATION": LocationProperty,
2355        "PARTITIONED_BY": PartitionedByProperty,
2356        "RETURNS": ReturnsProperty,
2357        "ROW_FORMAT": RowFormatProperty,
2358        "SORTKEY": SortKeyProperty,
2359    }
2360
2361    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2362
2363    # CREATE property locations
2364    # Form: schema specified
2365    #   create [POST_CREATE]
2366    #     table a [POST_NAME]
2367    #     (b int) [POST_SCHEMA]
2368    #     with ([POST_WITH])
2369    #     index (b) [POST_INDEX]
2370    #
2371    # Form: alias selection
2372    #   create [POST_CREATE]
2373    #     table a [POST_NAME]
2374    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2375    #     index (c) [POST_INDEX]
2376    class Location(AutoName):
2377        POST_CREATE = auto()
2378        POST_NAME = auto()
2379        POST_SCHEMA = auto()
2380        POST_WITH = auto()
2381        POST_ALIAS = auto()
2382        POST_EXPRESSION = auto()
2383        POST_INDEX = auto()
2384        UNSUPPORTED = auto()
2385
2386    @classmethod
2387    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2388        expressions = []
2389        for key, value in properties_dict.items():
2390            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2391            if property_cls:
2392                expressions.append(property_cls(this=convert(value)))
2393            else:
2394                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2395
2396        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:
2386    @classmethod
2387    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2388        expressions = []
2389        for key, value in properties_dict.items():
2390            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2391            if property_cls:
2392                expressions.append(property_cls(this=convert(value)))
2393            else:
2394                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2395
2396        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2376    class Location(AutoName):
2377        POST_CREATE = auto()
2378        POST_NAME = auto()
2379        POST_SCHEMA = auto()
2380        POST_WITH = auto()
2381        POST_ALIAS = auto()
2382        POST_EXPRESSION = auto()
2383        POST_INDEX = auto()
2384        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):
2399class Qualify(Expression):
2400    pass
key = 'qualify'
class InputOutputFormat(Expression):
2403class InputOutputFormat(Expression):
2404    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2408class Return(Expression):
2409    pass
key = 'return'
class Reference(Expression):
2412class Reference(Expression):
2413    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2416class Tuple(Expression):
2417    arg_types = {"expressions": False}
2418
2419    def isin(
2420        self,
2421        *expressions: t.Any,
2422        query: t.Optional[ExpOrStr] = None,
2423        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2424        copy: bool = True,
2425        **opts,
2426    ) -> In:
2427        return In(
2428            this=maybe_copy(self, copy),
2429            expressions=[convert(e, copy=copy) for e in expressions],
2430            query=maybe_parse(query, copy=copy, **opts) if query else None,
2431            unnest=(
2432                Unnest(
2433                    expressions=[
2434                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2435                        for e in ensure_list(unnest)
2436                    ]
2437                )
2438                if unnest
2439                else None
2440            ),
2441        )
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:
2419    def isin(
2420        self,
2421        *expressions: t.Any,
2422        query: t.Optional[ExpOrStr] = None,
2423        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2424        copy: bool = True,
2425        **opts,
2426    ) -> In:
2427        return In(
2428            this=maybe_copy(self, copy),
2429            expressions=[convert(e, copy=copy) for e in expressions],
2430            query=maybe_parse(query, copy=copy, **opts) if query else None,
2431            unnest=(
2432                Unnest(
2433                    expressions=[
2434                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2435                        for e in ensure_list(unnest)
2436                    ]
2437                )
2438                if unnest
2439                else None
2440            ),
2441        )
key = 'tuple'
class Subqueryable(Unionable):
2444class Subqueryable(Unionable):
2445    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2446        """
2447        Convert this expression to an aliased expression that can be used as a Subquery.
2448
2449        Example:
2450            >>> subquery = Select().select("x").from_("tbl").subquery()
2451            >>> Select().select("x").from_(subquery).sql()
2452            'SELECT x FROM (SELECT x FROM tbl)'
2453
2454        Args:
2455            alias (str | Identifier): an optional alias for the subquery
2456            copy (bool): if `False`, modify this expression instance in-place.
2457
2458        Returns:
2459            Alias: the subquery
2460        """
2461        instance = maybe_copy(self, copy)
2462        if not isinstance(alias, Expression):
2463            alias = TableAlias(this=to_identifier(alias)) if alias else None
2464
2465        return Subquery(this=instance, alias=alias)
2466
2467    def limit(
2468        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2469    ) -> Select:
2470        raise NotImplementedError
2471
2472    @property
2473    def ctes(self):
2474        with_ = self.args.get("with")
2475        if not with_:
2476            return []
2477        return with_.expressions
2478
2479    @property
2480    def selects(self) -> t.List[Expression]:
2481        raise NotImplementedError("Subqueryable objects must implement `selects`")
2482
2483    @property
2484    def named_selects(self) -> t.List[str]:
2485        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2486
2487    def select(
2488        self,
2489        *expressions: t.Optional[ExpOrStr],
2490        append: bool = True,
2491        dialect: DialectType = None,
2492        copy: bool = True,
2493        **opts,
2494    ) -> Subqueryable:
2495        raise NotImplementedError("Subqueryable objects must implement `select`")
2496
2497    def with_(
2498        self,
2499        alias: ExpOrStr,
2500        as_: ExpOrStr,
2501        recursive: t.Optional[bool] = None,
2502        append: bool = True,
2503        dialect: DialectType = None,
2504        copy: bool = True,
2505        **opts,
2506    ) -> Subqueryable:
2507        """
2508        Append to or set the common table expressions.
2509
2510        Example:
2511            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2512            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2513
2514        Args:
2515            alias: the SQL code string to parse as the table name.
2516                If an `Expression` instance is passed, this is used as-is.
2517            as_: the SQL code string to parse as the table expression.
2518                If an `Expression` instance is passed, it will be used as-is.
2519            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2520            append: if `True`, add to any existing expressions.
2521                Otherwise, this resets the expressions.
2522            dialect: the dialect used to parse the input expression.
2523            copy: if `False`, modify this expression instance in-place.
2524            opts: other options to use to parse the input expressions.
2525
2526        Returns:
2527            The modified expression.
2528        """
2529        return _apply_cte_builder(
2530            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2531        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2445    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2446        """
2447        Convert this expression to an aliased expression that can be used as a Subquery.
2448
2449        Example:
2450            >>> subquery = Select().select("x").from_("tbl").subquery()
2451            >>> Select().select("x").from_(subquery).sql()
2452            'SELECT x FROM (SELECT x FROM tbl)'
2453
2454        Args:
2455            alias (str | Identifier): an optional alias for the subquery
2456            copy (bool): if `False`, modify this expression instance in-place.
2457
2458        Returns:
2459            Alias: the subquery
2460        """
2461        instance = maybe_copy(self, copy)
2462        if not isinstance(alias, Expression):
2463            alias = TableAlias(this=to_identifier(alias)) if alias else None
2464
2465        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:
2467    def limit(
2468        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2469    ) -> Select:
2470        raise NotImplementedError
ctes
2472    @property
2473    def ctes(self):
2474        with_ = self.args.get("with")
2475        if not with_:
2476            return []
2477        return with_.expressions
selects: List[Expression]
2479    @property
2480    def selects(self) -> t.List[Expression]:
2481        raise NotImplementedError("Subqueryable objects must implement `selects`")
named_selects: List[str]
2483    @property
2484    def named_selects(self) -> t.List[str]:
2485        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:
2487    def select(
2488        self,
2489        *expressions: t.Optional[ExpOrStr],
2490        append: bool = True,
2491        dialect: DialectType = None,
2492        copy: bool = True,
2493        **opts,
2494    ) -> Subqueryable:
2495        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:
2497    def with_(
2498        self,
2499        alias: ExpOrStr,
2500        as_: ExpOrStr,
2501        recursive: t.Optional[bool] = None,
2502        append: bool = True,
2503        dialect: DialectType = None,
2504        copy: bool = True,
2505        **opts,
2506    ) -> Subqueryable:
2507        """
2508        Append to or set the common table expressions.
2509
2510        Example:
2511            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2512            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2513
2514        Args:
2515            alias: the SQL code string to parse as the table name.
2516                If an `Expression` instance is passed, this is used as-is.
2517            as_: the SQL code string to parse as the table expression.
2518                If an `Expression` instance is passed, it will be used as-is.
2519            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2520            append: if `True`, add to any existing expressions.
2521                Otherwise, this resets the expressions.
2522            dialect: the dialect used to parse the input expression.
2523            copy: if `False`, modify this expression instance in-place.
2524            opts: other options to use to parse the input expressions.
2525
2526        Returns:
2527            The modified expression.
2528        """
2529        return _apply_cte_builder(
2530            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2531        )

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

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

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

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

Checks whether an expression is a star.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

output_name: str
3530    @property
3531    def output_name(self) -> str:
3532        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):
3535class TableSample(Expression):
3536    arg_types = {
3537        "this": False,
3538        "expressions": False,
3539        "method": False,
3540        "bucket_numerator": False,
3541        "bucket_denominator": False,
3542        "bucket_field": False,
3543        "percent": False,
3544        "rows": False,
3545        "size": False,
3546        "seed": False,
3547    }
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):
3550class Tag(Expression):
3551    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3552
3553    arg_types = {
3554        "this": False,
3555        "prefix": False,
3556        "postfix": False,
3557    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3562class Pivot(Expression):
3563    arg_types = {
3564        "this": False,
3565        "alias": False,
3566        "expressions": False,
3567        "field": False,
3568        "unpivot": False,
3569        "using": False,
3570        "group": False,
3571        "columns": False,
3572        "include_nulls": False,
3573    }
3574
3575    @property
3576    def unpivot(self) -> bool:
3577        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
3575    @property
3576    def unpivot(self) -> bool:
3577        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3580class Window(Condition):
3581    arg_types = {
3582        "this": True,
3583        "partition_by": False,
3584        "order": False,
3585        "spec": False,
3586        "alias": False,
3587        "over": False,
3588        "first": False,
3589    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3592class WindowSpec(Expression):
3593    arg_types = {
3594        "kind": False,
3595        "start": False,
3596        "start_side": False,
3597        "end": False,
3598        "end_side": False,
3599    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3602class Where(Expression):
3603    pass
key = 'where'
class Star(Expression):
3606class Star(Expression):
3607    arg_types = {"except": False, "replace": False}
3608
3609    @property
3610    def name(self) -> str:
3611        return "*"
3612
3613    @property
3614    def output_name(self) -> str:
3615        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3609    @property
3610    def name(self) -> str:
3611        return "*"
output_name: str
3613    @property
3614    def output_name(self) -> str:
3615        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):
3618class Parameter(Condition):
3619    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3622class SessionParameter(Condition):
3623    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3626class Placeholder(Condition):
3627    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3630class Null(Condition):
3631    arg_types: t.Dict[str, t.Any] = {}
3632
3633    @property
3634    def name(self) -> str:
3635        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3633    @property
3634    def name(self) -> str:
3635        return "NULL"
key = 'null'
class Boolean(Condition):
3638class Boolean(Condition):
3639    pass
key = 'boolean'
class DataTypeParam(Expression):
3642class DataTypeParam(Expression):
3643    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3646class DataType(Expression):
3647    arg_types = {
3648        "this": True,
3649        "expressions": False,
3650        "nested": False,
3651        "values": False,
3652        "prefix": False,
3653        "kind": False,
3654    }
3655
3656    class Type(AutoName):
3657        ARRAY = auto()
3658        AGGREGATEFUNCTION = auto()
3659        SIMPLEAGGREGATEFUNCTION = auto()
3660        BIGDECIMAL = auto()
3661        BIGINT = auto()
3662        BIGSERIAL = auto()
3663        BINARY = auto()
3664        BIT = auto()
3665        BOOLEAN = auto()
3666        BPCHAR = 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        copy: bool = True,
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            copy: whether or not to copy the data type.
3820            kwargs: additional arguments to pass in the constructor of DataType.
3821
3822        Returns:
3823            The constructed DataType object.
3824        """
3825        from sqlglot import parse_one
3826
3827        if isinstance(dtype, str):
3828            if dtype.upper() == "UNKNOWN":
3829                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3830
3831            try:
3832                data_type_exp = parse_one(
3833                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3834                )
3835            except ParseError:
3836                if udt:
3837                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3838                raise
3839        elif isinstance(dtype, DataType.Type):
3840            data_type_exp = DataType(this=dtype)
3841        elif isinstance(dtype, DataType):
3842            return maybe_copy(dtype, copy)
3843        else:
3844            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3845
3846        return DataType(**{**data_type_exp.args, **kwargs})
3847
3848    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3849        """
3850        Checks whether this DataType matches one of the provided data types. Nested types or precision
3851        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3852
3853        Args:
3854            dtypes: the data types to compare this DataType to.
3855
3856        Returns:
3857            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3858        """
3859        for dtype in dtypes:
3860            other = DataType.build(dtype, copy=False, udt=True)
3861
3862            if (
3863                other.expressions
3864                or self.this == DataType.Type.USERDEFINED
3865                or other.this == DataType.Type.USERDEFINED
3866            ):
3867                matches = self == other
3868            else:
3869                matches = self.this == other.this
3870
3871            if matches:
3872                return True
3873        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>}
INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.INT: 'INT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>}
TEMPORAL_TYPES = {<Type.DATE32: 'DATE32'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME: 'DATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMETZ: 'TIMETZ'>}
@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, copy: bool = True, **kwargs) -> DataType:
3802    @classmethod
3803    def build(
3804        cls,
3805        dtype: DATA_TYPE,
3806        dialect: DialectType = None,
3807        udt: bool = False,
3808        copy: bool = True,
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            copy: whether or not to copy the data type.
3820            kwargs: additional arguments to pass in the constructor of DataType.
3821
3822        Returns:
3823            The constructed DataType object.
3824        """
3825        from sqlglot import parse_one
3826
3827        if isinstance(dtype, str):
3828            if dtype.upper() == "UNKNOWN":
3829                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3830
3831            try:
3832                data_type_exp = parse_one(
3833                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3834                )
3835            except ParseError:
3836                if udt:
3837                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3838                raise
3839        elif isinstance(dtype, DataType.Type):
3840            data_type_exp = DataType(this=dtype)
3841        elif isinstance(dtype, DataType):
3842            return maybe_copy(dtype, copy)
3843        else:
3844            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3845
3846        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.
  • copy: whether or not to copy the data type.
  • kwargs: 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:
3848    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3849        """
3850        Checks whether this DataType matches one of the provided data types. Nested types or precision
3851        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3852
3853        Args:
3854            dtypes: the data types to compare this DataType to.
3855
3856        Returns:
3857            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3858        """
3859        for dtype in dtypes:
3860            other = DataType.build(dtype, copy=False, udt=True)
3861
3862            if (
3863                other.expressions
3864                or self.this == DataType.Type.USERDEFINED
3865                or other.this == DataType.Type.USERDEFINED
3866            ):
3867                matches = self == other
3868            else:
3869                matches = self.this == other.this
3870
3871            if matches:
3872                return True
3873        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):
3656    class Type(AutoName):
3657        ARRAY = auto()
3658        AGGREGATEFUNCTION = auto()
3659        SIMPLEAGGREGATEFUNCTION = auto()
3660        BIGDECIMAL = auto()
3661        BIGINT = auto()
3662        BIGSERIAL = auto()
3663        BINARY = auto()
3664        BIT = auto()
3665        BOOLEAN = auto()
3666        BPCHAR = 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()

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'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
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):
3880class PseudoType(DataType):
3881    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3885class ObjectIdentifier(DataType):
3886    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3890class SubqueryPredicate(Predicate):
3891    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3894class All(SubqueryPredicate):
3895    pass
key = 'all'
class Any(SubqueryPredicate):
3898class Any(SubqueryPredicate):
3899    pass
key = 'any'
class Exists(SubqueryPredicate):
3902class Exists(SubqueryPredicate):
3903    pass
key = 'exists'
class Command(Expression):
3908class Command(Expression):
3909    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3912class Transaction(Expression):
3913    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3916class Commit(Expression):
3917    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3920class Rollback(Expression):
3921    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3924class AlterTable(Expression):
3925    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):
3928class AddConstraint(Expression):
3929    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3932class DropPartition(Expression):
3933    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3937class Binary(Condition):
3938    arg_types = {"this": True, "expression": True}
3939
3940    @property
3941    def left(self) -> Expression:
3942        return self.this
3943
3944    @property
3945    def right(self) -> Expression:
3946        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3940    @property
3941    def left(self) -> Expression:
3942        return self.this
right: Expression
3944    @property
3945    def right(self) -> Expression:
3946        return self.expression
key = 'binary'
class Add(Binary):
3949class Add(Binary):
3950    pass
key = 'add'
class Connector(Binary):
3953class Connector(Binary):
3954    pass
key = 'connector'
class And(Connector):
3957class And(Connector):
3958    pass
key = 'and'
class Or(Connector):
3961class Or(Connector):
3962    pass
key = 'or'
class BitwiseAnd(Binary):
3965class BitwiseAnd(Binary):
3966    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3969class BitwiseLeftShift(Binary):
3970    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3973class BitwiseOr(Binary):
3974    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3977class BitwiseRightShift(Binary):
3978    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3981class BitwiseXor(Binary):
3982    pass
key = 'bitwisexor'
class Div(Binary):
3985class Div(Binary):
3986    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):
3989class Overlaps(Binary):
3990    pass
key = 'overlaps'
class Dot(Binary):
3993class Dot(Binary):
3994    @property
3995    def name(self) -> str:
3996        return self.expression.name
3997
3998    @property
3999    def output_name(self) -> str:
4000        return self.name
4001
4002    @classmethod
4003    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4004        """Build a Dot object with a sequence of expressions."""
4005        if len(expressions) < 2:
4006            raise ValueError("Dot requires >= 2 expressions.")
4007
4008        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4009
4010    @property
4011    def parts(self) -> t.List[Expression]:
4012        """Return the parts of a table / column in order catalog, db, table."""
4013        this, *parts = self.flatten()
4014
4015        parts.reverse()
4016
4017        for arg in ("this", "table", "db", "catalog"):
4018            part = this.args.get(arg)
4019
4020            if isinstance(part, Expression):
4021                parts.append(part)
4022
4023        parts.reverse()
4024        return parts
name: str
3994    @property
3995    def name(self) -> str:
3996        return self.expression.name
output_name: str
3998    @property
3999    def output_name(self) -> str:
4000        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:
4002    @classmethod
4003    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4004        """Build a Dot object with a sequence of expressions."""
4005        if len(expressions) < 2:
4006            raise ValueError("Dot requires >= 2 expressions.")
4007
4008        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]
4010    @property
4011    def parts(self) -> t.List[Expression]:
4012        """Return the parts of a table / column in order catalog, db, table."""
4013        this, *parts = self.flatten()
4014
4015        parts.reverse()
4016
4017        for arg in ("this", "table", "db", "catalog"):
4018            part = this.args.get(arg)
4019
4020            if isinstance(part, Expression):
4021                parts.append(part)
4022
4023        parts.reverse()
4024        return parts

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

key = 'dot'
class DPipe(Binary):
4027class DPipe(Binary):
4028    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4031class EQ(Binary, Predicate):
4032    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4035class NullSafeEQ(Binary, Predicate):
4036    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4039class NullSafeNEQ(Binary, Predicate):
4040    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4044class PropertyEQ(Binary):
4045    pass
key = 'propertyeq'
class Distance(Binary):
4048class Distance(Binary):
4049    pass
key = 'distance'
class Escape(Binary):
4052class Escape(Binary):
4053    pass
key = 'escape'
class Glob(Binary, Predicate):
4056class Glob(Binary, Predicate):
4057    pass
key = 'glob'
class GT(Binary, Predicate):
4060class GT(Binary, Predicate):
4061    pass
key = 'gt'
class GTE(Binary, Predicate):
4064class GTE(Binary, Predicate):
4065    pass
key = 'gte'
class ILike(Binary, Predicate):
4068class ILike(Binary, Predicate):
4069    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4072class ILikeAny(Binary, Predicate):
4073    pass
key = 'ilikeany'
class IntDiv(Binary):
4076class IntDiv(Binary):
4077    pass
key = 'intdiv'
class Is(Binary, Predicate):
4080class Is(Binary, Predicate):
4081    pass
key = 'is'
class Kwarg(Binary):
4084class Kwarg(Binary):
4085    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4088class Like(Binary, Predicate):
4089    pass
key = 'like'
class LikeAny(Binary, Predicate):
4092class LikeAny(Binary, Predicate):
4093    pass
key = 'likeany'
class LT(Binary, Predicate):
4096class LT(Binary, Predicate):
4097    pass
key = 'lt'
class LTE(Binary, Predicate):
4100class LTE(Binary, Predicate):
4101    pass
key = 'lte'
class Mod(Binary):
4104class Mod(Binary):
4105    pass
key = 'mod'
class Mul(Binary):
4108class Mul(Binary):
4109    pass
key = 'mul'
class NEQ(Binary, Predicate):
4112class NEQ(Binary, Predicate):
4113    pass
key = 'neq'
class Operator(Binary):
4117class Operator(Binary):
4118    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4121class SimilarTo(Binary, Predicate):
4122    pass
key = 'similarto'
class Slice(Binary):
4125class Slice(Binary):
4126    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4129class Sub(Binary):
4130    pass
key = 'sub'
class Unary(Condition):
4135class Unary(Condition):
4136    pass
key = 'unary'
class BitwiseNot(Unary):
4139class BitwiseNot(Unary):
4140    pass
key = 'bitwisenot'
class Not(Unary):
4143class Not(Unary):
4144    pass
key = 'not'
class Paren(Unary):
4147class Paren(Unary):
4148    arg_types = {"this": True, "with": False}
4149
4150    @property
4151    def output_name(self) -> str:
4152        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4150    @property
4151    def output_name(self) -> str:
4152        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):
4155class Neg(Unary):
4156    pass
key = 'neg'
class Alias(Expression):
4159class Alias(Expression):
4160    arg_types = {"this": True, "alias": False}
4161
4162    @property
4163    def output_name(self) -> str:
4164        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4162    @property
4163    def output_name(self) -> str:
4164        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):
4169class PivotAlias(Alias):
4170    pass
key = 'pivotalias'
class Aliases(Expression):
4173class Aliases(Expression):
4174    arg_types = {"this": True, "expressions": True}
4175
4176    @property
4177    def aliases(self):
4178        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4176    @property
4177    def aliases(self):
4178        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4182class AtIndex(Expression):
4183    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4186class AtTimeZone(Expression):
4187    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4190class FromTimeZone(Expression):
4191    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4194class Between(Predicate):
4195    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4198class Bracket(Condition):
4199    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4200    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4201
4202    @property
4203    def output_name(self) -> str:
4204        if len(self.expressions) == 1:
4205            return self.expressions[0].output_name
4206
4207        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4202    @property
4203    def output_name(self) -> str:
4204        if len(self.expressions) == 1:
4205            return self.expressions[0].output_name
4206
4207        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):
4210class Distinct(Expression):
4211    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4214class In(Predicate):
4215    arg_types = {
4216        "this": True,
4217        "expressions": False,
4218        "query": False,
4219        "unnest": False,
4220        "field": False,
4221        "is_global": False,
4222    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4226class ForIn(Expression):
4227    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4230class TimeUnit(Expression):
4231    """Automatically converts unit arg into a var."""
4232
4233    arg_types = {"unit": False}
4234
4235    UNABBREVIATED_UNIT_NAME = {
4236        "D": "DAY",
4237        "H": "HOUR",
4238        "M": "MINUTE",
4239        "MS": "MILLISECOND",
4240        "NS": "NANOSECOND",
4241        "Q": "QUARTER",
4242        "S": "SECOND",
4243        "US": "MICROSECOND",
4244        "W": "WEEK",
4245        "Y": "YEAR",
4246    }
4247
4248    VAR_LIKE = (Column, Literal, Var)
4249
4250    def __init__(self, **args):
4251        unit = args.get("unit")
4252        if isinstance(unit, self.VAR_LIKE):
4253            args["unit"] = Var(
4254                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4255            )
4256        elif isinstance(unit, Week):
4257            unit.set("this", Var(this=unit.this.name.upper()))
4258
4259        super().__init__(**args)
4260
4261    @property
4262    def unit(self) -> t.Optional[Var]:
4263        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4250    def __init__(self, **args):
4251        unit = args.get("unit")
4252        if isinstance(unit, self.VAR_LIKE):
4253            args["unit"] = Var(
4254                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4255            )
4256        elif isinstance(unit, Week):
4257            unit.set("this", Var(this=unit.this.name.upper()))
4258
4259        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]
4261    @property
4262    def unit(self) -> t.Optional[Var]:
4263        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4266class IntervalOp(TimeUnit):
4267    arg_types = {"unit": True, "expression": True}
4268
4269    def interval(self):
4270        return Interval(
4271            this=self.expression.copy(),
4272            unit=self.unit.copy(),
4273        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4269    def interval(self):
4270        return Interval(
4271            this=self.expression.copy(),
4272            unit=self.unit.copy(),
4273        )
key = 'intervalop'
class IntervalSpan(DataType):
4279class IntervalSpan(DataType):
4280    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4283class Interval(TimeUnit):
4284    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4287class IgnoreNulls(Expression):
4288    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4291class RespectNulls(Expression):
4292    pass
key = 'respectnulls'
class HavingMax(Expression):
4296class HavingMax(Expression):
4297    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4301class Func(Condition):
4302    """
4303    The base class for all function expressions.
4304
4305    Attributes:
4306        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4307            treated as a variable length argument and the argument's value will be stored as a list.
4308        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4309            for this function expression. These values are used to map this node to a name during parsing
4310            as well as to provide the function's name during SQL string generation. By default the SQL
4311            name is set to the expression's class name transformed to snake case.
4312    """
4313
4314    is_var_len_args = False
4315
4316    @classmethod
4317    def from_arg_list(cls, args):
4318        if cls.is_var_len_args:
4319            all_arg_keys = list(cls.arg_types)
4320            # If this function supports variable length argument treat the last argument as such.
4321            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4322            num_non_var = len(non_var_len_arg_keys)
4323
4324            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4325            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4326        else:
4327            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4328
4329        return cls(**args_dict)
4330
4331    @classmethod
4332    def sql_names(cls):
4333        if cls is Func:
4334            raise NotImplementedError(
4335                "SQL name is only supported by concrete function implementations"
4336            )
4337        if "_sql_names" not in cls.__dict__:
4338            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4339        return cls._sql_names
4340
4341    @classmethod
4342    def sql_name(cls):
4343        return cls.sql_names()[0]
4344
4345    @classmethod
4346    def default_parser_mappings(cls):
4347        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):
4316    @classmethod
4317    def from_arg_list(cls, args):
4318        if cls.is_var_len_args:
4319            all_arg_keys = list(cls.arg_types)
4320            # If this function supports variable length argument treat the last argument as such.
4321            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4322            num_non_var = len(non_var_len_arg_keys)
4323
4324            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4325            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4326        else:
4327            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4328
4329        return cls(**args_dict)
@classmethod
def sql_names(cls):
4331    @classmethod
4332    def sql_names(cls):
4333        if cls is Func:
4334            raise NotImplementedError(
4335                "SQL name is only supported by concrete function implementations"
4336            )
4337        if "_sql_names" not in cls.__dict__:
4338            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4339        return cls._sql_names
@classmethod
def sql_name(cls):
4341    @classmethod
4342    def sql_name(cls):
4343        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4345    @classmethod
4346    def default_parser_mappings(cls):
4347        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4350class AggFunc(Func):
4351    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4354class ParameterizedAgg(AggFunc):
4355    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4358class Abs(Func):
4359    pass
key = 'abs'
class ArgMax(AggFunc):
4362class ArgMax(AggFunc):
4363    arg_types = {"this": True, "expression": True, "count": False}
4364    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4367class ArgMin(AggFunc):
4368    arg_types = {"this": True, "expression": True, "count": False}
4369    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4372class ApproxTopK(AggFunc):
4373    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4376class Flatten(Func):
4377    pass
key = 'flatten'
class Transform(Func):
4381class Transform(Func):
4382    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4385class Anonymous(Func):
4386    arg_types = {"this": True, "expressions": False}
4387    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4390class AnonymousAggFunc(AggFunc):
4391    arg_types = {"this": True, "expressions": False}
4392    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4396class CombinedAggFunc(AnonymousAggFunc):
4397    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4400class CombinedParameterizedAgg(ParameterizedAgg):
4401    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):
4406class Hll(AggFunc):
4407    arg_types = {"this": True, "expressions": False}
4408    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4411class ApproxDistinct(AggFunc):
4412    arg_types = {"this": True, "accuracy": False}
4413    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4416class Array(Func):
4417    arg_types = {"expressions": False}
4418    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4422class ToArray(Func):
4423    pass
key = 'toarray'
class ToChar(Func):
4428class ToChar(Func):
4429    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4432class GenerateSeries(Func):
4433    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4436class ArrayAgg(AggFunc):
4437    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4440class ArrayUniqueAgg(AggFunc):
4441    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4444class ArrayAll(Func):
4445    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4448class ArrayAny(Func):
4449    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4452class ArrayConcat(Func):
4453    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4454    arg_types = {"this": True, "expressions": False}
4455    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4458class ArrayContains(Binary, Func):
4459    pass
key = 'arraycontains'
class ArrayContained(Binary):
4462class ArrayContained(Binary):
4463    pass
key = 'arraycontained'
class ArrayFilter(Func):
4466class ArrayFilter(Func):
4467    arg_types = {"this": True, "expression": True}
4468    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4471class ArrayJoin(Func):
4472    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4475class ArrayOverlaps(Binary, Func):
4476    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4479class ArraySize(Func):
4480    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4483class ArraySort(Func):
4484    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4487class ArraySum(Func):
4488    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4491class ArrayUnionAgg(AggFunc):
4492    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4495class Avg(AggFunc):
4496    pass
key = 'avg'
class AnyValue(AggFunc):
4499class AnyValue(AggFunc):
4500    pass
key = 'anyvalue'
class Lag(AggFunc):
4503class Lag(AggFunc):
4504    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4507class Lead(AggFunc):
4508    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4513class First(AggFunc):
4514    pass
key = 'first'
class Last(AggFunc):
4517class Last(AggFunc):
4518    pass
key = 'last'
class FirstValue(AggFunc):
4521class FirstValue(AggFunc):
4522    pass
key = 'firstvalue'
class LastValue(AggFunc):
4525class LastValue(AggFunc):
4526    pass
key = 'lastvalue'
class NthValue(AggFunc):
4529class NthValue(AggFunc):
4530    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4533class Case(Func):
4534    arg_types = {"this": False, "ifs": True, "default": False}
4535
4536    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4537        instance = maybe_copy(self, copy)
4538        instance.append(
4539            "ifs",
4540            If(
4541                this=maybe_parse(condition, copy=copy, **opts),
4542                true=maybe_parse(then, copy=copy, **opts),
4543            ),
4544        )
4545        return instance
4546
4547    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4548        instance = maybe_copy(self, copy)
4549        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4550        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:
4536    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4537        instance = maybe_copy(self, copy)
4538        instance.append(
4539            "ifs",
4540            If(
4541                this=maybe_parse(condition, copy=copy, **opts),
4542                true=maybe_parse(then, copy=copy, **opts),
4543            ),
4544        )
4545        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4547    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4548        instance = maybe_copy(self, copy)
4549        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4550        return instance
key = 'case'
class Cast(Func):
4553class Cast(Func):
4554    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4555
4556    @property
4557    def name(self) -> str:
4558        return self.this.name
4559
4560    @property
4561    def to(self) -> DataType:
4562        return self.args["to"]
4563
4564    @property
4565    def output_name(self) -> str:
4566        return self.name
4567
4568    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4569        """
4570        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4571        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4572        array<int> != array<float>.
4573
4574        Args:
4575            dtypes: the data types to compare this Cast's DataType to.
4576
4577        Returns:
4578            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4579        """
4580        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4556    @property
4557    def name(self) -> str:
4558        return self.this.name
to: DataType
4560    @property
4561    def to(self) -> DataType:
4562        return self.args["to"]
output_name: str
4564    @property
4565    def output_name(self) -> str:
4566        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:
4568    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4569        """
4570        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4571        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4572        array<int> != array<float>.
4573
4574        Args:
4575            dtypes: the data types to compare this Cast's DataType to.
4576
4577        Returns:
4578            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4579        """
4580        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):
4583class TryCast(Cast):
4584    pass
key = 'trycast'
class CastToStrType(Func):
4587class CastToStrType(Func):
4588    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4591class Collate(Binary, Func):
4592    pass
key = 'collate'
class Ceil(Func):
4595class Ceil(Func):
4596    arg_types = {"this": True, "decimals": False}
4597    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4600class Coalesce(Func):
4601    arg_types = {"this": True, "expressions": False}
4602    is_var_len_args = True
4603    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4606class Chr(Func):
4607    arg_types = {"this": True, "charset": False, "expressions": False}
4608    is_var_len_args = True
4609    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4612class Concat(Func):
4613    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4614    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4617class ConcatWs(Concat):
4618    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4621class Count(AggFunc):
4622    arg_types = {"this": False, "expressions": False}
4623    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4626class CountIf(AggFunc):
4627    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4630class CurrentDate(Func):
4631    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4634class CurrentDatetime(Func):
4635    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4638class CurrentTime(Func):
4639    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4642class CurrentTimestamp(Func):
4643    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4646class CurrentUser(Func):
4647    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4650class DateAdd(Func, IntervalOp):
4651    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4654class DateSub(Func, IntervalOp):
4655    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4658class DateDiff(Func, TimeUnit):
4659    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4660    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4663class DateTrunc(Func):
4664    arg_types = {"unit": True, "this": True, "zone": False}
4665
4666    def __init__(self, **args):
4667        unit = args.get("unit")
4668        if isinstance(unit, TimeUnit.VAR_LIKE):
4669            args["unit"] = Literal.string(
4670                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4671            )
4672        elif isinstance(unit, Week):
4673            unit.set("this", Literal.string(unit.this.name.upper()))
4674
4675        super().__init__(**args)
4676
4677    @property
4678    def unit(self) -> Expression:
4679        return self.args["unit"]
DateTrunc(**args)
4666    def __init__(self, **args):
4667        unit = args.get("unit")
4668        if isinstance(unit, TimeUnit.VAR_LIKE):
4669            args["unit"] = Literal.string(
4670                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4671            )
4672        elif isinstance(unit, Week):
4673            unit.set("this", Literal.string(unit.this.name.upper()))
4674
4675        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4677    @property
4678    def unit(self) -> Expression:
4679        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4682class DatetimeAdd(Func, IntervalOp):
4683    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4686class DatetimeSub(Func, IntervalOp):
4687    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4690class DatetimeDiff(Func, TimeUnit):
4691    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4694class DatetimeTrunc(Func, TimeUnit):
4695    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4698class DayOfWeek(Func):
4699    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4702class DayOfMonth(Func):
4703    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4706class DayOfYear(Func):
4707    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4710class ToDays(Func):
4711    pass
key = 'todays'
class WeekOfYear(Func):
4714class WeekOfYear(Func):
4715    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4718class MonthsBetween(Func):
4719    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4722class LastDay(Func, TimeUnit):
4723    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4724    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4727class Extract(Func):
4728    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4731class Timestamp(Func):
4732    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4735class TimestampAdd(Func, TimeUnit):
4736    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4739class TimestampSub(Func, TimeUnit):
4740    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4743class TimestampDiff(Func, TimeUnit):
4744    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4745    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4748class TimestampTrunc(Func, TimeUnit):
4749    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4752class TimeAdd(Func, TimeUnit):
4753    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4756class TimeSub(Func, TimeUnit):
4757    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4760class TimeDiff(Func, TimeUnit):
4761    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4764class TimeTrunc(Func, TimeUnit):
4765    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4768class DateFromParts(Func):
4769    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4770    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4773class TimeFromParts(Func):
4774    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4775    arg_types = {
4776        "hour": True,
4777        "min": True,
4778        "sec": True,
4779        "nano": False,
4780        "fractions": False,
4781        "precision": False,
4782    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4785class DateStrToDate(Func):
4786    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4789class DateToDateStr(Func):
4790    pass
key = 'datetodatestr'
class DateToDi(Func):
4793class DateToDi(Func):
4794    pass
key = 'datetodi'
class Date(Func):
4798class Date(Func):
4799    arg_types = {"this": False, "zone": False, "expressions": False}
4800    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4803class Day(Func):
4804    pass
key = 'day'
class Decode(Func):
4807class Decode(Func):
4808    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4811class DiToDate(Func):
4812    pass
key = 'ditodate'
class Encode(Func):
4815class Encode(Func):
4816    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4819class Exp(Func):
4820    pass
key = 'exp'
class Explode(Func):
4824class Explode(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 = 'explode'
class ExplodeOuter(Explode):
4829class ExplodeOuter(Explode):
4830    pass
key = 'explodeouter'
class Posexplode(Explode):
4833class Posexplode(Explode):
4834    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4837class PosexplodeOuter(Posexplode):
4838    pass
key = 'posexplodeouter'
class Floor(Func):
4841class Floor(Func):
4842    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4845class FromBase64(Func):
4846    pass
key = 'frombase64'
class ToBase64(Func):
4849class ToBase64(Func):
4850    pass
key = 'tobase64'
class Greatest(Func):
4853class Greatest(Func):
4854    arg_types = {"this": True, "expressions": False}
4855    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4858class GroupConcat(AggFunc):
4859    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4862class Hex(Func):
4863    pass
key = 'hex'
class Xor(Connector, Func):
4866class Xor(Connector, Func):
4867    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4870class If(Func):
4871    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4874class Nullif(Func):
4875    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4878class Initcap(Func):
4879    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4882class IsNan(Func):
4883    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4886class IsInf(Func):
4887    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
4890class JSONPath(Expression):
4891    arg_types = {"expressions": True}
4892
4893    @property
4894    def output_name(self) -> str:
4895        last_segment = self.expressions[-1].this
4896        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
4893    @property
4894    def output_name(self) -> str:
4895        last_segment = self.expressions[-1].this
4896        return last_segment if isinstance(last_segment, str) else ""

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 = 'jsonpath'
class JSONPathPart(Expression):
4899class JSONPathPart(Expression):
4900    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
4903class JSONPathFilter(JSONPathPart):
4904    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
4907class JSONPathKey(JSONPathPart):
4908    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
4911class JSONPathRecursive(JSONPathPart):
4912    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
4915class JSONPathRoot(JSONPathPart):
4916    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
4919class JSONPathScript(JSONPathPart):
4920    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
4923class JSONPathSlice(JSONPathPart):
4924    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
4927class JSONPathSelector(JSONPathPart):
4928    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
4931class JSONPathSubscript(JSONPathPart):
4932    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
4935class JSONPathUnion(JSONPathPart):
4936    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
4939class JSONPathWildcard(JSONPathPart):
4940    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
4943class FormatJson(Expression):
4944    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4947class JSONKeyValue(Expression):
4948    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4951class JSONObject(Func):
4952    arg_types = {
4953        "expressions": False,
4954        "null_handling": False,
4955        "unique_keys": False,
4956        "return_type": False,
4957        "encoding": False,
4958    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
4961class JSONObjectAgg(AggFunc):
4962    arg_types = {
4963        "expressions": False,
4964        "null_handling": False,
4965        "unique_keys": False,
4966        "return_type": False,
4967        "encoding": False,
4968    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
4972class JSONArray(Func):
4973    arg_types = {
4974        "expressions": True,
4975        "null_handling": False,
4976        "return_type": False,
4977        "strict": False,
4978    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4982class JSONArrayAgg(Func):
4983    arg_types = {
4984        "this": True,
4985        "order": False,
4986        "null_handling": False,
4987        "return_type": False,
4988        "strict": False,
4989    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4994class JSONColumnDef(Expression):
4995    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):
4998class JSONSchema(Expression):
4999    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5003class JSONTable(Func):
5004    arg_types = {
5005        "this": True,
5006        "schema": True,
5007        "path": False,
5008        "error_handling": False,
5009        "empty_handling": False,
5010    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5013class OpenJSONColumnDef(Expression):
5014    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):
5017class OpenJSON(Func):
5018    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5021class JSONBContains(Binary):
5022    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5025class JSONExtract(Binary, Func):
5026    arg_types = {"this": True, "expression": True, "expressions": False}
5027    _sql_names = ["JSON_EXTRACT"]
5028    is_var_len_args = True
5029
5030    @property
5031    def output_name(self) -> str:
5032        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'expressions': False}
is_var_len_args = True
output_name: str
5030    @property
5031    def output_name(self) -> str:
5032        return self.expression.output_name if not self.expressions else ""

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 = 'jsonextract'
class JSONExtractScalar(Binary, Func):
5035class JSONExtractScalar(Binary, Func):
5036    arg_types = {"this": True, "expression": True, "expressions": False}
5037    _sql_names = ["JSON_EXTRACT_SCALAR"]
5038    is_var_len_args = True
5039
5040    @property
5041    def output_name(self) -> str:
5042        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'expressions': False}
is_var_len_args = True
output_name: str
5040    @property
5041    def output_name(self) -> str:
5042        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 = 'jsonextractscalar'
class JSONBExtract(Binary, Func):
5045class JSONBExtract(Binary, Func):
5046    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5049class JSONBExtractScalar(Binary, Func):
5050    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5053class JSONFormat(Func):
5054    arg_types = {"this": False, "options": False}
5055    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5059class JSONArrayContains(Binary, Predicate, Func):
5060    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5063class ParseJSON(Func):
5064    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5065    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5066    arg_types = {"this": True, "expressions": False}
5067    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5070class Least(Func):
5071    arg_types = {"this": True, "expressions": False}
5072    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5075class Left(Func):
5076    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5083class Length(Func):
5084    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5087class Levenshtein(Func):
5088    arg_types = {
5089        "this": True,
5090        "expression": False,
5091        "ins_cost": False,
5092        "del_cost": False,
5093        "sub_cost": False,
5094    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5097class Ln(Func):
5098    pass
key = 'ln'
class Log(Func):
5101class Log(Func):
5102    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5105class Log2(Func):
5106    pass
key = 'log2'
class Log10(Func):
5109class Log10(Func):
5110    pass
key = 'log10'
class LogicalOr(AggFunc):
5113class LogicalOr(AggFunc):
5114    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5117class LogicalAnd(AggFunc):
5118    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5121class Lower(Func):
5122    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5125class Map(Func):
5126    arg_types = {"keys": False, "values": False}
5127
5128    @property
5129    def keys(self) -> t.List[Expression]:
5130        keys = self.args.get("keys")
5131        return keys.expressions if keys else []
5132
5133    @property
5134    def values(self) -> t.List[Expression]:
5135        values = self.args.get("values")
5136        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5128    @property
5129    def keys(self) -> t.List[Expression]:
5130        keys = self.args.get("keys")
5131        return keys.expressions if keys else []
values: List[Expression]
5133    @property
5134    def values(self) -> t.List[Expression]:
5135        values = self.args.get("values")
5136        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5139class MapFromEntries(Func):
5140    pass
key = 'mapfromentries'
class StarMap(Func):
5143class StarMap(Func):
5144    pass
key = 'starmap'
class VarMap(Func):
5147class VarMap(Func):
5148    arg_types = {"keys": True, "values": True}
5149    is_var_len_args = True
5150
5151    @property
5152    def keys(self) -> t.List[Expression]:
5153        return self.args["keys"].expressions
5154
5155    @property
5156    def values(self) -> t.List[Expression]:
5157        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5151    @property
5152    def keys(self) -> t.List[Expression]:
5153        return self.args["keys"].expressions
values: List[Expression]
5155    @property
5156    def values(self) -> t.List[Expression]:
5157        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5161class MatchAgainst(Func):
5162    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5165class Max(AggFunc):
5166    arg_types = {"this": True, "expressions": False}
5167    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5170class MD5(Func):
5171    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5175class MD5Digest(Func):
5176    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5179class Min(AggFunc):
5180    arg_types = {"this": True, "expressions": False}
5181    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5184class Month(Func):
5185    pass
key = 'month'
class Nvl2(Func):
5188class Nvl2(Func):
5189    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5193class Predict(Func):
5194    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5197class Pow(Binary, Func):
5198    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5201class PercentileCont(AggFunc):
5202    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5205class PercentileDisc(AggFunc):
5206    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5209class Quantile(AggFunc):
5210    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5213class ApproxQuantile(Quantile):
5214    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):
5217class Rand(Func):
5218    _sql_names = ["RAND", "RANDOM"]
5219    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5222class Randn(Func):
5223    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5226class RangeN(Func):
5227    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5230class ReadCSV(Func):
5231    _sql_names = ["READ_CSV"]
5232    is_var_len_args = True
5233    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5236class Reduce(Func):
5237    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):
5240class RegexpExtract(Func):
5241    arg_types = {
5242        "this": True,
5243        "expression": True,
5244        "position": False,
5245        "occurrence": False,
5246        "parameters": False,
5247        "group": False,
5248    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5251class RegexpReplace(Func):
5252    arg_types = {
5253        "this": True,
5254        "expression": True,
5255        "replacement": False,
5256        "position": False,
5257        "occurrence": False,
5258        "parameters": False,
5259        "modifiers": False,
5260    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5263class RegexpLike(Binary, Func):
5264    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5267class RegexpILike(Binary, Func):
5268    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5273class RegexpSplit(Func):
5274    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5277class Repeat(Func):
5278    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5283class Round(Func):
5284    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5287class RowNumber(Func):
5288    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5291class SafeDivide(Func):
5292    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5295class SHA(Func):
5296    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5299class SHA2(Func):
5300    _sql_names = ["SHA2"]
5301    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5304class SortArray(Func):
5305    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5308class Split(Func):
5309    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5314class Substring(Func):
5315    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5318class StandardHash(Func):
5319    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5322class StartsWith(Func):
5323    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5324    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5327class StrPosition(Func):
5328    arg_types = {
5329        "this": True,
5330        "substr": True,
5331        "position": False,
5332        "instance": False,
5333    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5336class StrToDate(Func):
5337    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5340class StrToTime(Func):
5341    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5346class StrToUnix(Func):
5347    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5352class StrToMap(Func):
5353    arg_types = {
5354        "this": True,
5355        "pair_delim": False,
5356        "key_value_delim": False,
5357        "duplicate_resolution_callback": False,
5358    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5361class NumberToStr(Func):
5362    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5365class FromBase(Func):
5366    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5369class Struct(Func):
5370    arg_types = {"expressions": False}
5371    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5374class StructExtract(Func):
5375    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5380class Stuff(Func):
5381    _sql_names = ["STUFF", "INSERT"]
5382    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):
5385class Sum(AggFunc):
5386    pass
key = 'sum'
class Sqrt(Func):
5389class Sqrt(Func):
5390    pass
key = 'sqrt'
class Stddev(AggFunc):
5393class Stddev(AggFunc):
5394    pass
key = 'stddev'
class StddevPop(AggFunc):
5397class StddevPop(AggFunc):
5398    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5401class StddevSamp(AggFunc):
5402    pass
key = 'stddevsamp'
class TimeToStr(Func):
5405class TimeToStr(Func):
5406    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5409class TimeToTimeStr(Func):
5410    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5413class TimeToUnix(Func):
5414    pass
key = 'timetounix'
class TimeStrToDate(Func):
5417class TimeStrToDate(Func):
5418    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5421class TimeStrToTime(Func):
5422    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5425class TimeStrToUnix(Func):
5426    pass
key = 'timestrtounix'
class Trim(Func):
5429class Trim(Func):
5430    arg_types = {
5431        "this": True,
5432        "expression": False,
5433        "position": False,
5434        "collation": False,
5435    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5438class TsOrDsAdd(Func, TimeUnit):
5439    # return_type is used to correctly cast the arguments of this expression when transpiling it
5440    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5441
5442    @property
5443    def return_type(self) -> DataType:
5444        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
5442    @property
5443    def return_type(self) -> DataType:
5444        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5447class TsOrDsDiff(Func, TimeUnit):
5448    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5451class TsOrDsToDateStr(Func):
5452    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5455class TsOrDsToDate(Func):
5456    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5459class TsOrDsToTime(Func):
5460    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5463class TsOrDiToDi(Func):
5464    pass
key = 'tsorditodi'
class Unhex(Func):
5467class Unhex(Func):
5468    pass
key = 'unhex'
class UnixDate(Func):
5472class UnixDate(Func):
5473    pass
key = 'unixdate'
class UnixToStr(Func):
5476class UnixToStr(Func):
5477    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5482class UnixToTime(Func):
5483    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5484
5485    SECONDS = Literal.number(0)
5486    DECIS = Literal.number(1)
5487    CENTIS = Literal.number(2)
5488    MILLIS = Literal.number(3)
5489    DECIMILLIS = Literal.number(4)
5490    CENTIMILLIS = Literal.number(5)
5491    MICROS = Literal.number(6)
5492    DECIMICROS = Literal.number(7)
5493    CENTIMICROS = Literal.number(8)
5494    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):
5497class UnixToTimeStr(Func):
5498    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5501class TimestampFromParts(Func):
5502    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5503    arg_types = {
5504        "year": True,
5505        "month": True,
5506        "day": True,
5507        "hour": True,
5508        "min": True,
5509        "sec": True,
5510        "nano": False,
5511        "zone": False,
5512        "milli": False,
5513    }
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):
5516class Upper(Func):
5517    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5520class Variance(AggFunc):
5521    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5524class VariancePop(AggFunc):
5525    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5528class Week(Func):
5529    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5532class XMLTable(Func):
5533    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):
5536class Year(Func):
5537    pass
key = 'year'
class Use(Expression):
5540class Use(Expression):
5541    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5544class Merge(Expression):
5545    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):
5548class When(Func):
5549    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):
5554class NextValueFor(Func):
5555    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 'ArrayOverlaps'>, <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 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <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 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <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 'NthValue'>, <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_OVERLAPS': <class 'ArrayOverlaps'>, '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'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, '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'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, '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'>, 'NTH_VALUE': <class 'NthValue'>, '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'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, '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'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
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:
5595def maybe_parse(
5596    sql_or_expression: ExpOrStr,
5597    *,
5598    into: t.Optional[IntoType] = None,
5599    dialect: DialectType = None,
5600    prefix: t.Optional[str] = None,
5601    copy: bool = False,
5602    **opts,
5603) -> Expression:
5604    """Gracefully handle a possible string or expression.
5605
5606    Example:
5607        >>> maybe_parse("1")
5608        Literal(this=1, is_string=False)
5609        >>> maybe_parse(to_identifier("x"))
5610        Identifier(this=x, quoted=False)
5611
5612    Args:
5613        sql_or_expression: the SQL code string or an expression
5614        into: the SQLGlot Expression to parse into
5615        dialect: the dialect used to parse the input expressions (in the case that an
5616            input expression is a SQL string).
5617        prefix: a string to prefix the sql with before it gets parsed
5618            (automatically includes a space)
5619        copy: whether or not to copy the expression.
5620        **opts: other options to use to parse the input expressions (again, in the case
5621            that an input expression is a SQL string).
5622
5623    Returns:
5624        Expression: the parsed or given expression.
5625    """
5626    if isinstance(sql_or_expression, Expression):
5627        if copy:
5628            return sql_or_expression.copy()
5629        return sql_or_expression
5630
5631    if sql_or_expression is None:
5632        raise ParseError("SQL cannot be None")
5633
5634    import sqlglot
5635
5636    sql = str(sql_or_expression)
5637    if prefix:
5638        sql = f"{prefix} {sql}"
5639
5640    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):
5653def maybe_copy(instance, copy=True):
5654    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:
5868def union(
5869    left: ExpOrStr,
5870    right: ExpOrStr,
5871    distinct: bool = True,
5872    dialect: DialectType = None,
5873    copy: bool = True,
5874    **opts,
5875) -> Union:
5876    """
5877    Initializes a syntax tree from one UNION expression.
5878
5879    Example:
5880        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5881        'SELECT * FROM foo UNION SELECT * FROM bla'
5882
5883    Args:
5884        left: the SQL code string corresponding to the left-hand side.
5885            If an `Expression` instance is passed, it will be used as-is.
5886        right: the SQL code string corresponding to the right-hand side.
5887            If an `Expression` instance is passed, it will be used as-is.
5888        distinct: set the DISTINCT flag if and only if this is true.
5889        dialect: the dialect used to parse the input expression.
5890        copy: whether or not to copy the expression.
5891        opts: other options to use to parse the input expressions.
5892
5893    Returns:
5894        The new Union instance.
5895    """
5896    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5897    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5898
5899    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:
5902def intersect(
5903    left: ExpOrStr,
5904    right: ExpOrStr,
5905    distinct: bool = True,
5906    dialect: DialectType = None,
5907    copy: bool = True,
5908    **opts,
5909) -> Intersect:
5910    """
5911    Initializes a syntax tree from one INTERSECT expression.
5912
5913    Example:
5914        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5915        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5916
5917    Args:
5918        left: the SQL code string corresponding to the left-hand side.
5919            If an `Expression` instance is passed, it will be used as-is.
5920        right: the SQL code string corresponding to the right-hand side.
5921            If an `Expression` instance is passed, it will be used as-is.
5922        distinct: set the DISTINCT flag if and only if this is true.
5923        dialect: the dialect used to parse the input expression.
5924        copy: whether or not to copy the expression.
5925        opts: other options to use to parse the input expressions.
5926
5927    Returns:
5928        The new Intersect instance.
5929    """
5930    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5931    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5932
5933    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:
5936def except_(
5937    left: ExpOrStr,
5938    right: ExpOrStr,
5939    distinct: bool = True,
5940    dialect: DialectType = None,
5941    copy: bool = True,
5942    **opts,
5943) -> Except:
5944    """
5945    Initializes a syntax tree from one EXCEPT expression.
5946
5947    Example:
5948        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5949        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5950
5951    Args:
5952        left: the SQL code string corresponding to the left-hand side.
5953            If an `Expression` instance is passed, it will be used as-is.
5954        right: the SQL code string corresponding to the right-hand side.
5955            If an `Expression` instance is passed, it will be used as-is.
5956        distinct: set the DISTINCT flag if and only if this is true.
5957        dialect: the dialect used to parse the input expression.
5958        copy: whether or not to copy the expression.
5959        opts: other options to use to parse the input expressions.
5960
5961    Returns:
5962        The new Except instance.
5963    """
5964    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5965    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5966
5967    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:
5970def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5971    """
5972    Initializes a syntax tree from one or multiple SELECT expressions.
5973
5974    Example:
5975        >>> select("col1", "col2").from_("tbl").sql()
5976        'SELECT col1, col2 FROM tbl'
5977
5978    Args:
5979        *expressions: the SQL code string to parse as the expressions of a
5980            SELECT statement. If an Expression instance is passed, this is used as-is.
5981        dialect: the dialect used to parse the input expressions (in the case that an
5982            input expression is a SQL string).
5983        **opts: other options to use to parse the input expressions (again, in the case
5984            that an input expression is a SQL string).
5985
5986    Returns:
5987        Select: the syntax tree for the SELECT statement.
5988    """
5989    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:
5992def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5993    """
5994    Initializes a syntax tree from a FROM expression.
5995
5996    Example:
5997        >>> from_("tbl").select("col1", "col2").sql()
5998        'SELECT col1, col2 FROM tbl'
5999
6000    Args:
6001        *expression: the SQL code string to parse as the FROM expressions of a
6002            SELECT statement. If an Expression instance is passed, this is used as-is.
6003        dialect: the dialect used to parse the input expression (in the case that the
6004            input expression is a SQL string).
6005        **opts: other options to use to parse the input expressions (again, in the case
6006            that the input expression is a SQL string).
6007
6008    Returns:
6009        Select: the syntax tree for the SELECT statement.
6010    """
6011    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:
6014def update(
6015    table: str | Table,
6016    properties: dict,
6017    where: t.Optional[ExpOrStr] = None,
6018    from_: t.Optional[ExpOrStr] = None,
6019    dialect: DialectType = None,
6020    **opts,
6021) -> Update:
6022    """
6023    Creates an update statement.
6024
6025    Example:
6026        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6027        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6028
6029    Args:
6030        *properties: dictionary of properties to set which are
6031            auto converted to sql objects eg None -> NULL
6032        where: sql conditional parsed into a WHERE statement
6033        from_: sql statement parsed into a FROM statement
6034        dialect: the dialect used to parse the input expressions.
6035        **opts: other options to use to parse the input expressions.
6036
6037    Returns:
6038        Update: the syntax tree for the UPDATE statement.
6039    """
6040    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6041    update_expr.set(
6042        "expressions",
6043        [
6044            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6045            for k, v in properties.items()
6046        ],
6047    )
6048    if from_:
6049        update_expr.set(
6050            "from",
6051            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6052        )
6053    if isinstance(where, Condition):
6054        where = Where(this=where)
6055    if where:
6056        update_expr.set(
6057            "where",
6058            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6059        )
6060    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:
6063def delete(
6064    table: ExpOrStr,
6065    where: t.Optional[ExpOrStr] = None,
6066    returning: t.Optional[ExpOrStr] = None,
6067    dialect: DialectType = None,
6068    **opts,
6069) -> Delete:
6070    """
6071    Builds a delete statement.
6072
6073    Example:
6074        >>> delete("my_table", where="id > 1").sql()
6075        'DELETE FROM my_table WHERE id > 1'
6076
6077    Args:
6078        where: sql conditional parsed into a WHERE statement
6079        returning: sql conditional parsed into a RETURNING statement
6080        dialect: the dialect used to parse the input expressions.
6081        **opts: other options to use to parse the input expressions.
6082
6083    Returns:
6084        Delete: the syntax tree for the DELETE statement.
6085    """
6086    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6087    if where:
6088        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6089    if returning:
6090        delete_expr = t.cast(
6091            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6092        )
6093    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:
6096def insert(
6097    expression: ExpOrStr,
6098    into: ExpOrStr,
6099    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6100    overwrite: t.Optional[bool] = None,
6101    returning: t.Optional[ExpOrStr] = None,
6102    dialect: DialectType = None,
6103    copy: bool = True,
6104    **opts,
6105) -> Insert:
6106    """
6107    Builds an INSERT statement.
6108
6109    Example:
6110        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6111        'INSERT INTO tbl VALUES (1, 2, 3)'
6112
6113    Args:
6114        expression: the sql string or expression of the INSERT statement
6115        into: the tbl to insert data to.
6116        columns: optionally the table's column names.
6117        overwrite: whether to INSERT OVERWRITE or not.
6118        returning: sql conditional parsed into a RETURNING statement
6119        dialect: the dialect used to parse the input expressions.
6120        copy: whether or not to copy the expression.
6121        **opts: other options to use to parse the input expressions.
6122
6123    Returns:
6124        Insert: the syntax tree for the INSERT statement.
6125    """
6126    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6127    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6128
6129    if columns:
6130        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6131
6132    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6133
6134    if returning:
6135        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6136
6137    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:
6140def condition(
6141    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6142) -> Condition:
6143    """
6144    Initialize a logical condition expression.
6145
6146    Example:
6147        >>> condition("x=1").sql()
6148        'x = 1'
6149
6150        This is helpful for composing larger logical syntax trees:
6151        >>> where = condition("x=1")
6152        >>> where = where.and_("y=1")
6153        >>> Select().from_("tbl").select("*").where(where).sql()
6154        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6155
6156    Args:
6157        *expression: the SQL code string to parse.
6158            If an Expression instance is passed, this is used as-is.
6159        dialect: the dialect used to parse the input expression (in the case that the
6160            input expression is a SQL string).
6161        copy: Whether or not to copy `expression` (only applies to expressions).
6162        **opts: other options to use to parse the input expressions (again, in the case
6163            that the input expression is a SQL string).
6164
6165    Returns:
6166        The new Condition instance
6167    """
6168    return maybe_parse(
6169        expression,
6170        into=Condition,
6171        dialect=dialect,
6172        copy=copy,
6173        **opts,
6174    )

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:
6177def and_(
6178    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6179) -> Condition:
6180    """
6181    Combine multiple conditions with an AND logical operator.
6182
6183    Example:
6184        >>> and_("x=1", and_("y=1", "z=1")).sql()
6185        'x = 1 AND (y = 1 AND z = 1)'
6186
6187    Args:
6188        *expressions: the SQL code strings to parse.
6189            If an Expression instance is passed, this is used as-is.
6190        dialect: the dialect used to parse the input expression.
6191        copy: whether or not to copy `expressions` (only applies to Expressions).
6192        **opts: other options to use to parse the input expressions.
6193
6194    Returns:
6195        And: the new condition
6196    """
6197    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:
6200def or_(
6201    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6202) -> Condition:
6203    """
6204    Combine multiple conditions with an OR logical operator.
6205
6206    Example:
6207        >>> or_("x=1", or_("y=1", "z=1")).sql()
6208        'x = 1 OR (y = 1 OR z = 1)'
6209
6210    Args:
6211        *expressions: the SQL code strings to parse.
6212            If an Expression instance is passed, this is used as-is.
6213        dialect: the dialect used to parse the input expression.
6214        copy: whether or not to copy `expressions` (only applies to Expressions).
6215        **opts: other options to use to parse the input expressions.
6216
6217    Returns:
6218        Or: the new condition
6219    """
6220    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:
6223def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6224    """
6225    Wrap a condition with a NOT operator.
6226
6227    Example:
6228        >>> not_("this_suit='black'").sql()
6229        "NOT this_suit = 'black'"
6230
6231    Args:
6232        expression: the SQL code string to parse.
6233            If an Expression instance is passed, this is used as-is.
6234        dialect: the dialect used to parse the input expression.
6235        copy: whether to copy the expression or not.
6236        **opts: other options to use to parse the input expressions.
6237
6238    Returns:
6239        The new condition.
6240    """
6241    this = condition(
6242        expression,
6243        dialect=dialect,
6244        copy=copy,
6245        **opts,
6246    )
6247    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:
6250def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6251    """
6252    Wrap an expression in parentheses.
6253
6254    Example:
6255        >>> paren("5 + 3").sql()
6256        '(5 + 3)'
6257
6258    Args:
6259        expression: the SQL code string to parse.
6260            If an Expression instance is passed, this is used as-is.
6261        copy: whether to copy the expression or not.
6262
6263    Returns:
6264        The wrapped expression.
6265    """
6266    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: Pattern[str] = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
6284def to_identifier(name, quoted=None, copy=True):
6285    """Builds an identifier.
6286
6287    Args:
6288        name: The name to turn into an identifier.
6289        quoted: Whether or not force quote the identifier.
6290        copy: Whether or not to copy name if it's an Identifier.
6291
6292    Returns:
6293        The identifier ast node.
6294    """
6295
6296    if name is None:
6297        return None
6298
6299    if isinstance(name, Identifier):
6300        identifier = maybe_copy(name, copy)
6301    elif isinstance(name, str):
6302        identifier = Identifier(
6303            this=name,
6304            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6305        )
6306    else:
6307        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6308    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:
6311def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6312    """
6313    Parses a given string into an identifier.
6314
6315    Args:
6316        name: The name to parse into an identifier.
6317        dialect: The dialect to parse against.
6318
6319    Returns:
6320        The identifier ast node.
6321    """
6322    try:
6323        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6324    except ParseError:
6325        expression = to_identifier(name)
6326
6327    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:
6333def to_interval(interval: str | Literal) -> Interval:
6334    """Builds an interval expression from a string like '1 day' or '5 months'."""
6335    if isinstance(interval, Literal):
6336        if not interval.is_string:
6337            raise ValueError("Invalid interval string.")
6338
6339        interval = interval.this
6340
6341    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6342
6343    if not interval_parts:
6344        raise ValueError("Invalid interval string.")
6345
6346    return Interval(
6347        this=Literal.string(interval_parts.group(1)),
6348        unit=Var(this=interval_parts.group(2).upper()),
6349    )

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]:
6362def to_table(
6363    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6364) -> t.Optional[Table]:
6365    """
6366    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6367    If a table is passed in then that table is returned.
6368
6369    Args:
6370        sql_path: a `[catalog].[schema].[table]` string.
6371        dialect: the source dialect according to which the table name will be parsed.
6372        copy: Whether or not to copy a table if it is passed in.
6373        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6374
6375    Returns:
6376        A table expression.
6377    """
6378    if sql_path is None or isinstance(sql_path, Table):
6379        return maybe_copy(sql_path, copy=copy)
6380    if not isinstance(sql_path, str):
6381        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6382
6383    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6384    if table:
6385        for k, v in kwargs.items():
6386            table.set(k, v)
6387
6388    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:
6391def to_column(sql_path: str | Column, **kwargs) -> Column:
6392    """
6393    Create a column from a `[table].[column]` sql path. Schema is optional.
6394
6395    If a column is passed in then that column is returned.
6396
6397    Args:
6398        sql_path: `[table].[column]` string
6399    Returns:
6400        Table: A column expression
6401    """
6402    if sql_path is None or isinstance(sql_path, Column):
6403        return sql_path
6404    if not isinstance(sql_path, str):
6405        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6406    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):
6409def alias_(
6410    expression: ExpOrStr,
6411    alias: str | Identifier,
6412    table: bool | t.Sequence[str | Identifier] = False,
6413    quoted: t.Optional[bool] = None,
6414    dialect: DialectType = None,
6415    copy: bool = True,
6416    **opts,
6417):
6418    """Create an Alias expression.
6419
6420    Example:
6421        >>> alias_('foo', 'bar').sql()
6422        'foo AS bar'
6423
6424        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6425        '(SELECT 1, 2) AS bar(a, b)'
6426
6427    Args:
6428        expression: the SQL code strings to parse.
6429            If an Expression instance is passed, this is used as-is.
6430        alias: the alias name to use. If the name has
6431            special characters it is quoted.
6432        table: Whether or not to create a table alias, can also be a list of columns.
6433        quoted: whether or not to quote the alias
6434        dialect: the dialect used to parse the input expression.
6435        copy: Whether or not to copy the expression.
6436        **opts: other options to use to parse the input expressions.
6437
6438    Returns:
6439        Alias: the aliased expression
6440    """
6441    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6442    alias = to_identifier(alias, quoted=quoted)
6443
6444    if table:
6445        table_alias = TableAlias(this=alias)
6446        exp.set("alias", table_alias)
6447
6448        if not isinstance(table, bool):
6449            for column in table:
6450                table_alias.append("columns", to_identifier(column, quoted=quoted))
6451
6452        return exp
6453
6454    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6455    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6456    # for the complete Window expression.
6457    #
6458    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6459
6460    if "alias" in exp.arg_types and not isinstance(exp, Window):
6461        exp.set("alias", alias)
6462        return exp
6463    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:
6466def subquery(
6467    expression: ExpOrStr,
6468    alias: t.Optional[Identifier | str] = None,
6469    dialect: DialectType = None,
6470    **opts,
6471) -> Select:
6472    """
6473    Build a subquery expression.
6474
6475    Example:
6476        >>> subquery('select x from tbl', 'bar').select('x').sql()
6477        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6478
6479    Args:
6480        expression: the SQL code strings to parse.
6481            If an Expression instance is passed, this is used as-is.
6482        alias: the alias name to use.
6483        dialect: the dialect used to parse the input expression.
6484        **opts: other options to use to parse the input expressions.
6485
6486    Returns:
6487        A new Select instance with the subquery expression included.
6488    """
6489
6490    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6491    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):
6522def column(
6523    col,
6524    table=None,
6525    db=None,
6526    catalog=None,
6527    *,
6528    fields=None,
6529    quoted=None,
6530    copy=True,
6531):
6532    """
6533    Build a Column.
6534
6535    Args:
6536        col: Column name.
6537        table: Table name.
6538        db: Database name.
6539        catalog: Catalog name.
6540        fields: Additional fields using dots.
6541        quoted: Whether to force quotes on the column's identifiers.
6542        copy: Whether or not to copy identifiers if passed in.
6543
6544    Returns:
6545        The new Column instance.
6546    """
6547    this = Column(
6548        this=to_identifier(col, quoted=quoted, copy=copy),
6549        table=to_identifier(table, quoted=quoted, copy=copy),
6550        db=to_identifier(db, quoted=quoted, copy=copy),
6551        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6552    )
6553
6554    if fields:
6555        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6556    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], copy: bool = True, **opts) -> Cast:
6559def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6560    """Cast an expression to a data type.
6561
6562    Example:
6563        >>> cast('x + 1', 'int').sql()
6564        'CAST(x + 1 AS INT)'
6565
6566    Args:
6567        expression: The expression to cast.
6568        to: The datatype to cast to.
6569        copy: Whether or not to copy the supplied expressions.
6570
6571    Returns:
6572        The new Cast instance.
6573    """
6574    expression = maybe_parse(expression, copy=copy, **opts)
6575    data_type = DataType.build(to, copy=copy, **opts)
6576    expression = Cast(this=expression, to=data_type)
6577    expression.type = data_type
6578    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.
  • copy: Whether or not to copy the supplied expressions.
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:
6581def table_(
6582    table: Identifier | str,
6583    db: t.Optional[Identifier | str] = None,
6584    catalog: t.Optional[Identifier | str] = None,
6585    quoted: t.Optional[bool] = None,
6586    alias: t.Optional[Identifier | str] = None,
6587) -> Table:
6588    """Build a Table.
6589
6590    Args:
6591        table: Table name.
6592        db: Database name.
6593        catalog: Catalog name.
6594        quote: Whether to force quotes on the table's identifiers.
6595        alias: Table's alias.
6596
6597    Returns:
6598        The new Table instance.
6599    """
6600    return Table(
6601        this=to_identifier(table, quoted=quoted) if table else None,
6602        db=to_identifier(db, quoted=quoted) if db else None,
6603        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6604        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6605    )

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:
6608def values(
6609    values: t.Iterable[t.Tuple[t.Any, ...]],
6610    alias: t.Optional[str] = None,
6611    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6612) -> Values:
6613    """Build VALUES statement.
6614
6615    Example:
6616        >>> values([(1, '2')]).sql()
6617        "VALUES (1, '2')"
6618
6619    Args:
6620        values: values statements that will be converted to SQL
6621        alias: optional alias
6622        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6623         If either are provided then an alias is also required.
6624
6625    Returns:
6626        Values: the Values expression object
6627    """
6628    if columns and not alias:
6629        raise ValueError("Alias is required when providing columns")
6630
6631    return Values(
6632        expressions=[convert(tup) for tup in values],
6633        alias=(
6634            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6635            if columns
6636            else (TableAlias(this=to_identifier(alias)) if alias else None)
6637        ),
6638    )

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:
6641def var(name: t.Optional[ExpOrStr]) -> Var:
6642    """Build a SQL variable.
6643
6644    Example:
6645        >>> repr(var('x'))
6646        'Var(this=x)'
6647
6648        >>> repr(var(column('x', table='y')))
6649        'Var(this=x)'
6650
6651    Args:
6652        name: The name of the var or an expression who's name will become the var.
6653
6654    Returns:
6655        The new variable node.
6656    """
6657    if not name:
6658        raise ValueError("Cannot convert empty name into var.")
6659
6660    if isinstance(name, Expression):
6661        name = name.name
6662    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:
6665def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6666    """Build ALTER TABLE... RENAME... expression
6667
6668    Args:
6669        old_name: The old name of the table
6670        new_name: The new name of the table
6671
6672    Returns:
6673        Alter table expression
6674    """
6675    old_table = to_table(old_name)
6676    new_table = to_table(new_name)
6677    return AlterTable(
6678        this=old_table,
6679        actions=[
6680            RenameTable(this=new_table),
6681        ],
6682    )

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:
6685def rename_column(
6686    table_name: str | Table,
6687    old_column_name: str | Column,
6688    new_column_name: str | Column,
6689    exists: t.Optional[bool] = None,
6690) -> AlterTable:
6691    """Build ALTER TABLE... RENAME COLUMN... expression
6692
6693    Args:
6694        table_name: Name of the table
6695        old_column: The old name of the column
6696        new_column: The new name of the column
6697        exists: Whether or not to add the `IF EXISTS` clause
6698
6699    Returns:
6700        Alter table expression
6701    """
6702    table = to_table(table_name)
6703    old_column = to_column(old_column_name)
6704    new_column = to_column(new_column_name)
6705    return AlterTable(
6706        this=table,
6707        actions=[
6708            RenameColumn(this=old_column, to=new_column, exists=exists),
6709        ],
6710    )

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:
6713def convert(value: t.Any, copy: bool = False) -> Expression:
6714    """Convert a python value into an expression object.
6715
6716    Raises an error if a conversion is not possible.
6717
6718    Args:
6719        value: A python object.
6720        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6721
6722    Returns:
6723        Expression: the equivalent expression object.
6724    """
6725    if isinstance(value, Expression):
6726        return maybe_copy(value, copy)
6727    if isinstance(value, str):
6728        return Literal.string(value)
6729    if isinstance(value, bool):
6730        return Boolean(this=value)
6731    if value is None or (isinstance(value, float) and math.isnan(value)):
6732        return null()
6733    if isinstance(value, numbers.Number):
6734        return Literal.number(value)
6735    if isinstance(value, datetime.datetime):
6736        datetime_literal = Literal.string(
6737            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6738        )
6739        return TimeStrToTime(this=datetime_literal)
6740    if isinstance(value, datetime.date):
6741        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6742        return DateStrToDate(this=date_literal)
6743    if isinstance(value, tuple):
6744        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6745    if isinstance(value, list):
6746        return Array(expressions=[convert(v, copy=copy) for v in value])
6747    if isinstance(value, dict):
6748        return Map(
6749            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6750            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6751        )
6752    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:
6755def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6756    """
6757    Replace children of an expression with the result of a lambda fun(child) -> exp.
6758    """
6759    for k, v in expression.args.items():
6760        is_list_arg = type(v) is list
6761
6762        child_nodes = v if is_list_arg else [v]
6763        new_child_nodes = []
6764
6765        for cn in child_nodes:
6766            if isinstance(cn, Expression):
6767                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6768                    new_child_nodes.append(child_node)
6769                    child_node.parent = expression
6770                    child_node.arg_key = k
6771            else:
6772                new_child_nodes.append(cn)
6773
6774        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]:
6777def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6778    """
6779    Return all table names referenced through columns in an expression.
6780
6781    Example:
6782        >>> import sqlglot
6783        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6784        ['a', 'c']
6785
6786    Args:
6787        expression: expression to find table names.
6788        exclude: a table name to exclude
6789
6790    Returns:
6791        A list of unique names.
6792    """
6793    return {
6794        table
6795        for table in (column.table for column in expression.find_all(Column))
6796        if table and table != exclude
6797    }

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:
6800def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6801    """Get the full name of a table as a string.
6802
6803    Args:
6804        table: Table expression node or string.
6805        dialect: The dialect to generate the table name for.
6806        identify: Determines when an identifier should be quoted. Possible values are:
6807            False (default): Never quote, except in cases where it's mandatory by the dialect.
6808            True: Always quote.
6809
6810    Examples:
6811        >>> from sqlglot import exp, parse_one
6812        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6813        'a.b.c'
6814
6815    Returns:
6816        The table name.
6817    """
6818
6819    table = maybe_parse(table, into=Table, dialect=dialect)
6820
6821    if not table:
6822        raise ValueError(f"Cannot parse {table}")
6823
6824    return ".".join(
6825        (
6826            part.sql(dialect=dialect, identify=True, copy=False)
6827            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6828            else part.name
6829        )
6830        for part in table.parts
6831    )

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:
6834def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6835    """Returns a case normalized table name without quotes.
6836
6837    Args:
6838        table: the table to normalize
6839        dialect: the dialect to use for normalization rules
6840        copy: whether or not to copy the expression.
6841
6842    Examples:
6843        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6844        'A-B.c'
6845    """
6846    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6847
6848    return ".".join(
6849        p.name
6850        for p in normalize_identifiers(
6851            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6852        ).parts
6853    )

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:
6856def replace_tables(
6857    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6858) -> E:
6859    """Replace all tables in expression according to the mapping.
6860
6861    Args:
6862        expression: expression node to be transformed and replaced.
6863        mapping: mapping of table names.
6864        dialect: the dialect of the mapping table
6865        copy: whether or not to copy the expression.
6866
6867    Examples:
6868        >>> from sqlglot import exp, parse_one
6869        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6870        'SELECT * FROM c /* a.b */'
6871
6872    Returns:
6873        The mapped expression.
6874    """
6875
6876    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6877
6878    def _replace_tables(node: Expression) -> Expression:
6879        if isinstance(node, Table):
6880            original = normalize_table_name(node, dialect=dialect)
6881            new_name = mapping.get(original)
6882
6883            if new_name:
6884                table = to_table(
6885                    new_name,
6886                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6887                )
6888                table.add_comments([original])
6889                return table
6890        return node
6891
6892    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:
6895def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6896    """Replace placeholders in an expression.
6897
6898    Args:
6899        expression: expression node to be transformed and replaced.
6900        args: positional names that will substitute unnamed placeholders in the given order.
6901        kwargs: keyword arguments that will substitute named placeholders.
6902
6903    Examples:
6904        >>> from sqlglot import exp, parse_one
6905        >>> replace_placeholders(
6906        ...     parse_one("select * from :tbl where ? = ?"),
6907        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6908        ... ).sql()
6909        "SELECT * FROM foo WHERE str_col = 'b'"
6910
6911    Returns:
6912        The mapped expression.
6913    """
6914
6915    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6916        if isinstance(node, Placeholder):
6917            if node.name:
6918                new_name = kwargs.get(node.name)
6919                if new_name:
6920                    return convert(new_name)
6921            else:
6922                try:
6923                    return convert(next(args))
6924                except StopIteration:
6925                    pass
6926        return node
6927
6928    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:
6931def expand(
6932    expression: Expression,
6933    sources: t.Dict[str, Subqueryable],
6934    dialect: DialectType = None,
6935    copy: bool = True,
6936) -> Expression:
6937    """Transforms an expression by expanding all referenced sources into subqueries.
6938
6939    Examples:
6940        >>> from sqlglot import parse_one
6941        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6942        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6943
6944        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6945        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6946
6947    Args:
6948        expression: The expression to expand.
6949        sources: A dictionary of name to Subqueryables.
6950        dialect: The dialect of the sources dict.
6951        copy: Whether or not to copy the expression during transformation. Defaults to True.
6952
6953    Returns:
6954        The transformed expression.
6955    """
6956    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6957
6958    def _expand(node: Expression):
6959        if isinstance(node, Table):
6960            name = normalize_table_name(node, dialect=dialect)
6961            source = sources.get(name)
6962            if source:
6963                subquery = source.subquery(node.alias or name)
6964                subquery.comments = [f"source: {name}"]
6965                return subquery.transform(_expand, copy=False)
6966        return node
6967
6968    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:
6971def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6972    """
6973    Returns a Func expression.
6974
6975    Examples:
6976        >>> func("abs", 5).sql()
6977        'ABS(5)'
6978
6979        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6980        'CAST(5 AS DOUBLE)'
6981
6982    Args:
6983        name: the name of the function to build.
6984        args: the args used to instantiate the function of interest.
6985        copy: whether or not to copy the argument expressions.
6986        dialect: the source dialect.
6987        kwargs: the kwargs used to instantiate the function of interest.
6988
6989    Note:
6990        The arguments `args` and `kwargs` are mutually exclusive.
6991
6992    Returns:
6993        An instance of the function of interest, or an anonymous function, if `name` doesn't
6994        correspond to an existing `sqlglot.expressions.Func` class.
6995    """
6996    if args and kwargs:
6997        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6998
6999    from sqlglot.dialects.dialect import Dialect
7000
7001    dialect = Dialect.get_or_raise(dialect)
7002
7003    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7004    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7005
7006    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7007    if constructor:
7008        if converted:
7009            if "dialect" in constructor.__code__.co_varnames:
7010                function = constructor(converted, dialect=dialect)
7011            else:
7012                function = constructor(converted)
7013        elif constructor.__name__ == "from_arg_list":
7014            function = constructor.__self__(**kwargs)  # type: ignore
7015        else:
7016            constructor = FUNCTION_BY_NAME.get(name.upper())
7017            if constructor:
7018                function = constructor(**kwargs)
7019            else:
7020                raise ValueError(
7021                    f"Unable to convert '{name}' into a Func. Either manually construct "
7022                    "the Func expression of interest or parse the function call."
7023                )
7024    else:
7025        kwargs = kwargs or {"expressions": converted}
7026        function = Anonymous(this=name, **kwargs)
7027
7028    for error_message in function.error_messages(converted):
7029        raise ValueError(error_message)
7030
7031    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:
7034def case(
7035    expression: t.Optional[ExpOrStr] = None,
7036    **opts,
7037) -> Case:
7038    """
7039    Initialize a CASE statement.
7040
7041    Example:
7042        case().when("a = 1", "foo").else_("bar")
7043
7044    Args:
7045        expression: Optionally, the input expression (not all dialects support this)
7046        **opts: Extra keyword arguments for parsing `expression`
7047    """
7048    if expression is not None:
7049        this = maybe_parse(expression, **opts)
7050    else:
7051        this = None
7052    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:
7055def cast_unless(
7056    expression: ExpOrStr,
7057    to: DATA_TYPE,
7058    *types: DATA_TYPE,
7059    **opts: t.Any,
7060) -> Expression | Cast:
7061    """
7062    Cast an expression to a data type unless it is a specified type.
7063
7064    Args:
7065        expression: The expression to cast.
7066        to: The data type to cast to.
7067        **types: The types to exclude from casting.
7068        **opts: Extra keyword arguments for parsing `expression`
7069    """
7070    expr = maybe_parse(expression, **opts)
7071    if expr.is_type(*types):
7072        return expr
7073    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:
7076def true() -> Boolean:
7077    """
7078    Returns a true Boolean expression.
7079    """
7080    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7083def false() -> Boolean:
7084    """
7085    Returns a false Boolean expression.
7086    """
7087    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7090def null() -> Null:
7091    """
7092    Returns a Null expression.
7093    """
7094    return Null()

Returns a Null expression.