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}
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}
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# Functions
4295class Func(Condition):
4296    """
4297    The base class for all function expressions.
4298
4299    Attributes:
4300        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4301            treated as a variable length argument and the argument's value will be stored as a list.
4302        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4303            for this function expression. These values are used to map this node to a name during parsing
4304            as well as to provide the function's name during SQL string generation. By default the SQL
4305            name is set to the expression's class name transformed to snake case.
4306    """
4307
4308    is_var_len_args = False
4309
4310    @classmethod
4311    def from_arg_list(cls, args):
4312        if cls.is_var_len_args:
4313            all_arg_keys = list(cls.arg_types)
4314            # If this function supports variable length argument treat the last argument as such.
4315            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4316            num_non_var = len(non_var_len_arg_keys)
4317
4318            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4319            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4320        else:
4321            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4322
4323        return cls(**args_dict)
4324
4325    @classmethod
4326    def sql_names(cls):
4327        if cls is Func:
4328            raise NotImplementedError(
4329                "SQL name is only supported by concrete function implementations"
4330            )
4331        if "_sql_names" not in cls.__dict__:
4332            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4333        return cls._sql_names
4334
4335    @classmethod
4336    def sql_name(cls):
4337        return cls.sql_names()[0]
4338
4339    @classmethod
4340    def default_parser_mappings(cls):
4341        return {name: cls.from_arg_list for name in cls.sql_names()}
4342
4343
4344class AggFunc(Func):
4345    pass
4346
4347
4348class ParameterizedAgg(AggFunc):
4349    arg_types = {"this": True, "expressions": True, "params": True}
4350
4351
4352class Abs(Func):
4353    pass
4354
4355
4356class ArgMax(AggFunc):
4357    arg_types = {"this": True, "expression": True, "count": False}
4358    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
4359
4360
4361class ArgMin(AggFunc):
4362    arg_types = {"this": True, "expression": True, "count": False}
4363    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
4364
4365
4366class ApproxTopK(AggFunc):
4367    arg_types = {"this": True, "expression": False, "counters": False}
4368
4369
4370class Flatten(Func):
4371    pass
4372
4373
4374# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4375class Transform(Func):
4376    arg_types = {"this": True, "expression": True}
4377
4378
4379class Anonymous(Func):
4380    arg_types = {"this": True, "expressions": False}
4381    is_var_len_args = True
4382
4383
4384class AnonymousAggFunc(AggFunc):
4385    arg_types = {"this": True, "expressions": False}
4386    is_var_len_args = True
4387
4388
4389# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
4390class CombinedAggFunc(AnonymousAggFunc):
4391    arg_types = {"this": True, "expressions": False, "parts": True}
4392
4393
4394class CombinedParameterizedAgg(ParameterizedAgg):
4395    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
4396
4397
4398# https://docs.snowflake.com/en/sql-reference/functions/hll
4399# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4400class Hll(AggFunc):
4401    arg_types = {"this": True, "expressions": False}
4402    is_var_len_args = True
4403
4404
4405class ApproxDistinct(AggFunc):
4406    arg_types = {"this": True, "accuracy": False}
4407    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4408
4409
4410class Array(Func):
4411    arg_types = {"expressions": False}
4412    is_var_len_args = True
4413
4414
4415# https://docs.snowflake.com/en/sql-reference/functions/to_array
4416class ToArray(Func):
4417    pass
4418
4419
4420# https://docs.snowflake.com/en/sql-reference/functions/to_char
4421# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
4422class ToChar(Func):
4423    arg_types = {"this": True, "format": False, "nlsparam": False}
4424
4425
4426class GenerateSeries(Func):
4427    arg_types = {"start": True, "end": True, "step": False}
4428
4429
4430class ArrayAgg(AggFunc):
4431    pass
4432
4433
4434class ArrayUniqueAgg(AggFunc):
4435    pass
4436
4437
4438class ArrayAll(Func):
4439    arg_types = {"this": True, "expression": True}
4440
4441
4442class ArrayAny(Func):
4443    arg_types = {"this": True, "expression": True}
4444
4445
4446class ArrayConcat(Func):
4447    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4448    arg_types = {"this": True, "expressions": False}
4449    is_var_len_args = True
4450
4451
4452class ArrayContains(Binary, Func):
4453    pass
4454
4455
4456class ArrayContained(Binary):
4457    pass
4458
4459
4460class ArrayFilter(Func):
4461    arg_types = {"this": True, "expression": True}
4462    _sql_names = ["FILTER", "ARRAY_FILTER"]
4463
4464
4465class ArrayJoin(Func):
4466    arg_types = {"this": True, "expression": True, "null": False}
4467
4468
4469class ArrayOverlaps(Binary, Func):
4470    pass
4471
4472
4473class ArraySize(Func):
4474    arg_types = {"this": True, "expression": False}
4475
4476
4477class ArraySort(Func):
4478    arg_types = {"this": True, "expression": False}
4479
4480
4481class ArraySum(Func):
4482    arg_types = {"this": True, "expression": False}
4483
4484
4485class ArrayUnionAgg(AggFunc):
4486    pass
4487
4488
4489class Avg(AggFunc):
4490    pass
4491
4492
4493class AnyValue(AggFunc):
4494    arg_types = {"this": True, "having": False, "max": False}
4495
4496
4497class Lag(AggFunc):
4498    arg_types = {"this": True, "offset": False, "default": False}
4499
4500
4501class Lead(AggFunc):
4502    arg_types = {"this": True, "offset": False, "default": False}
4503
4504
4505# some dialects have a distinction between first and first_value, usually first is an aggregate func
4506# and first_value is a window func
4507class First(AggFunc):
4508    pass
4509
4510
4511class Last(AggFunc):
4512    pass
4513
4514
4515class FirstValue(AggFunc):
4516    pass
4517
4518
4519class LastValue(AggFunc):
4520    pass
4521
4522
4523class NthValue(AggFunc):
4524    arg_types = {"this": True, "offset": True}
4525
4526
4527class Case(Func):
4528    arg_types = {"this": False, "ifs": True, "default": False}
4529
4530    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4531        instance = maybe_copy(self, copy)
4532        instance.append(
4533            "ifs",
4534            If(
4535                this=maybe_parse(condition, copy=copy, **opts),
4536                true=maybe_parse(then, copy=copy, **opts),
4537            ),
4538        )
4539        return instance
4540
4541    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4542        instance = maybe_copy(self, copy)
4543        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4544        return instance
4545
4546
4547class Cast(Func):
4548    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4549
4550    @property
4551    def name(self) -> str:
4552        return self.this.name
4553
4554    @property
4555    def to(self) -> DataType:
4556        return self.args["to"]
4557
4558    @property
4559    def output_name(self) -> str:
4560        return self.name
4561
4562    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4563        """
4564        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4565        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4566        array<int> != array<float>.
4567
4568        Args:
4569            dtypes: the data types to compare this Cast's DataType to.
4570
4571        Returns:
4572            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4573        """
4574        return self.to.is_type(*dtypes)
4575
4576
4577class TryCast(Cast):
4578    pass
4579
4580
4581class CastToStrType(Func):
4582    arg_types = {"this": True, "to": True}
4583
4584
4585class Collate(Binary, Func):
4586    pass
4587
4588
4589class Ceil(Func):
4590    arg_types = {"this": True, "decimals": False}
4591    _sql_names = ["CEIL", "CEILING"]
4592
4593
4594class Coalesce(Func):
4595    arg_types = {"this": True, "expressions": False}
4596    is_var_len_args = True
4597    _sql_names = ["COALESCE", "IFNULL", "NVL"]
4598
4599
4600class Chr(Func):
4601    arg_types = {"this": True, "charset": False, "expressions": False}
4602    is_var_len_args = True
4603    _sql_names = ["CHR", "CHAR"]
4604
4605
4606class Concat(Func):
4607    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4608    is_var_len_args = True
4609
4610
4611class ConcatWs(Concat):
4612    _sql_names = ["CONCAT_WS"]
4613
4614
4615class Count(AggFunc):
4616    arg_types = {"this": False, "expressions": False}
4617    is_var_len_args = True
4618
4619
4620class CountIf(AggFunc):
4621    _sql_names = ["COUNT_IF", "COUNTIF"]
4622
4623
4624class CurrentDate(Func):
4625    arg_types = {"this": False}
4626
4627
4628class CurrentDatetime(Func):
4629    arg_types = {"this": False}
4630
4631
4632class CurrentTime(Func):
4633    arg_types = {"this": False}
4634
4635
4636class CurrentTimestamp(Func):
4637    arg_types = {"this": False, "transaction": False}
4638
4639
4640class CurrentUser(Func):
4641    arg_types = {"this": False}
4642
4643
4644class DateAdd(Func, IntervalOp):
4645    arg_types = {"this": True, "expression": True, "unit": False}
4646
4647
4648class DateSub(Func, IntervalOp):
4649    arg_types = {"this": True, "expression": True, "unit": False}
4650
4651
4652class DateDiff(Func, TimeUnit):
4653    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4654    arg_types = {"this": True, "expression": True, "unit": False}
4655
4656
4657class DateTrunc(Func):
4658    arg_types = {"unit": True, "this": True, "zone": False}
4659
4660    def __init__(self, **args):
4661        unit = args.get("unit")
4662        if isinstance(unit, TimeUnit.VAR_LIKE):
4663            args["unit"] = Literal.string(
4664                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4665            )
4666        elif isinstance(unit, Week):
4667            unit.set("this", Literal.string(unit.this.name.upper()))
4668
4669        super().__init__(**args)
4670
4671    @property
4672    def unit(self) -> Expression:
4673        return self.args["unit"]
4674
4675
4676class DatetimeAdd(Func, IntervalOp):
4677    arg_types = {"this": True, "expression": True, "unit": False}
4678
4679
4680class DatetimeSub(Func, IntervalOp):
4681    arg_types = {"this": True, "expression": True, "unit": False}
4682
4683
4684class DatetimeDiff(Func, TimeUnit):
4685    arg_types = {"this": True, "expression": True, "unit": False}
4686
4687
4688class DatetimeTrunc(Func, TimeUnit):
4689    arg_types = {"this": True, "unit": True, "zone": False}
4690
4691
4692class DayOfWeek(Func):
4693    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
4694
4695
4696class DayOfMonth(Func):
4697    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
4698
4699
4700class DayOfYear(Func):
4701    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
4702
4703
4704class ToDays(Func):
4705    pass
4706
4707
4708class WeekOfYear(Func):
4709    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
4710
4711
4712class MonthsBetween(Func):
4713    arg_types = {"this": True, "expression": True, "roundoff": False}
4714
4715
4716class LastDay(Func, TimeUnit):
4717    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4718    arg_types = {"this": True, "unit": False}
4719
4720
4721class Extract(Func):
4722    arg_types = {"this": True, "expression": True}
4723
4724
4725class Timestamp(Func):
4726    arg_types = {"this": False, "expression": False}
4727
4728
4729class TimestampAdd(Func, TimeUnit):
4730    arg_types = {"this": True, "expression": True, "unit": False}
4731
4732
4733class TimestampSub(Func, TimeUnit):
4734    arg_types = {"this": True, "expression": True, "unit": False}
4735
4736
4737class TimestampDiff(Func, TimeUnit):
4738    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4739    arg_types = {"this": True, "expression": True, "unit": False}
4740
4741
4742class TimestampTrunc(Func, TimeUnit):
4743    arg_types = {"this": True, "unit": True, "zone": False}
4744
4745
4746class TimeAdd(Func, TimeUnit):
4747    arg_types = {"this": True, "expression": True, "unit": False}
4748
4749
4750class TimeSub(Func, TimeUnit):
4751    arg_types = {"this": True, "expression": True, "unit": False}
4752
4753
4754class TimeDiff(Func, TimeUnit):
4755    arg_types = {"this": True, "expression": True, "unit": False}
4756
4757
4758class TimeTrunc(Func, TimeUnit):
4759    arg_types = {"this": True, "unit": True, "zone": False}
4760
4761
4762class DateFromParts(Func):
4763    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4764    arg_types = {"year": True, "month": True, "day": True}
4765
4766
4767class TimeFromParts(Func):
4768    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4769    arg_types = {
4770        "hour": True,
4771        "min": True,
4772        "sec": True,
4773        "nano": False,
4774        "fractions": False,
4775        "precision": False,
4776    }
4777
4778
4779class DateStrToDate(Func):
4780    pass
4781
4782
4783class DateToDateStr(Func):
4784    pass
4785
4786
4787class DateToDi(Func):
4788    pass
4789
4790
4791# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
4792class Date(Func):
4793    arg_types = {"this": False, "zone": False, "expressions": False}
4794    is_var_len_args = True
4795
4796
4797class Day(Func):
4798    pass
4799
4800
4801class Decode(Func):
4802    arg_types = {"this": True, "charset": True, "replace": False}
4803
4804
4805class DiToDate(Func):
4806    pass
4807
4808
4809class Encode(Func):
4810    arg_types = {"this": True, "charset": True}
4811
4812
4813class Exp(Func):
4814    pass
4815
4816
4817# https://docs.snowflake.com/en/sql-reference/functions/flatten
4818class Explode(Func):
4819    arg_types = {"this": True, "expressions": False}
4820    is_var_len_args = True
4821
4822
4823class ExplodeOuter(Explode):
4824    pass
4825
4826
4827class Posexplode(Explode):
4828    pass
4829
4830
4831class PosexplodeOuter(Posexplode):
4832    pass
4833
4834
4835class Floor(Func):
4836    arg_types = {"this": True, "decimals": False}
4837
4838
4839class FromBase64(Func):
4840    pass
4841
4842
4843class ToBase64(Func):
4844    pass
4845
4846
4847class Greatest(Func):
4848    arg_types = {"this": True, "expressions": False}
4849    is_var_len_args = True
4850
4851
4852class GroupConcat(AggFunc):
4853    arg_types = {"this": True, "separator": False}
4854
4855
4856class Hex(Func):
4857    pass
4858
4859
4860class Xor(Connector, Func):
4861    arg_types = {"this": False, "expression": False, "expressions": False}
4862
4863
4864class If(Func):
4865    arg_types = {"this": True, "true": True, "false": False}
4866
4867
4868class Nullif(Func):
4869    arg_types = {"this": True, "expression": True}
4870
4871
4872class Initcap(Func):
4873    arg_types = {"this": True, "expression": False}
4874
4875
4876class IsNan(Func):
4877    _sql_names = ["IS_NAN", "ISNAN"]
4878
4879
4880class IsInf(Func):
4881    _sql_names = ["IS_INF", "ISINF"]
4882
4883
4884class JSONPath(Expression):
4885    arg_types = {"expressions": True}
4886
4887    @property
4888    def output_name(self) -> str:
4889        last_segment = self.expressions[-1].this
4890        return last_segment if isinstance(last_segment, str) else ""
4891
4892
4893class JSONPathPart(Expression):
4894    arg_types = {}
4895
4896
4897class JSONPathFilter(JSONPathPart):
4898    arg_types = {"this": True}
4899
4900
4901class JSONPathKey(JSONPathPart):
4902    arg_types = {"this": True}
4903
4904
4905class JSONPathRecursive(JSONPathPart):
4906    arg_types = {"this": False}
4907
4908
4909class JSONPathRoot(JSONPathPart):
4910    pass
4911
4912
4913class JSONPathScript(JSONPathPart):
4914    arg_types = {"this": True}
4915
4916
4917class JSONPathSlice(JSONPathPart):
4918    arg_types = {"start": False, "end": False, "step": False}
4919
4920
4921class JSONPathSelector(JSONPathPart):
4922    arg_types = {"this": True}
4923
4924
4925class JSONPathSubscript(JSONPathPart):
4926    arg_types = {"this": True}
4927
4928
4929class JSONPathUnion(JSONPathPart):
4930    arg_types = {"expressions": True}
4931
4932
4933class JSONPathWildcard(JSONPathPart):
4934    pass
4935
4936
4937class FormatJson(Expression):
4938    pass
4939
4940
4941class JSONKeyValue(Expression):
4942    arg_types = {"this": True, "expression": True}
4943
4944
4945class JSONObject(Func):
4946    arg_types = {
4947        "expressions": False,
4948        "null_handling": False,
4949        "unique_keys": False,
4950        "return_type": False,
4951        "encoding": False,
4952    }
4953
4954
4955class JSONObjectAgg(AggFunc):
4956    arg_types = {
4957        "expressions": False,
4958        "null_handling": False,
4959        "unique_keys": False,
4960        "return_type": False,
4961        "encoding": False,
4962    }
4963
4964
4965# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
4966class JSONArray(Func):
4967    arg_types = {
4968        "expressions": True,
4969        "null_handling": False,
4970        "return_type": False,
4971        "strict": False,
4972    }
4973
4974
4975# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
4976class JSONArrayAgg(Func):
4977    arg_types = {
4978        "this": True,
4979        "order": False,
4980        "null_handling": False,
4981        "return_type": False,
4982        "strict": False,
4983    }
4984
4985
4986# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4987# Note: parsing of JSON column definitions is currently incomplete.
4988class JSONColumnDef(Expression):
4989    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
4990
4991
4992class JSONSchema(Expression):
4993    arg_types = {"expressions": True}
4994
4995
4996# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4997class JSONTable(Func):
4998    arg_types = {
4999        "this": True,
5000        "schema": True,
5001        "path": False,
5002        "error_handling": False,
5003        "empty_handling": False,
5004    }
5005
5006
5007class OpenJSONColumnDef(Expression):
5008    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
5009
5010
5011class OpenJSON(Func):
5012    arg_types = {"this": True, "path": False, "expressions": False}
5013
5014
5015class JSONBContains(Binary):
5016    _sql_names = ["JSONB_CONTAINS"]
5017
5018
5019class JSONExtract(Binary, Func):
5020    # MySQL and SQLite support a variant of JSON_EXTRACT where you can have multiple JSON
5021    # paths and you get back a list of values. These paths will be stored in `expressions`
5022    arg_types = {"this": True, "expression": True, "expressions": False}
5023    _sql_names = ["JSON_EXTRACT"]
5024
5025    @property
5026    def output_name(self) -> str:
5027        return self.expression.output_name if not self.expressions else ""
5028
5029
5030class JSONExtractScalar(Binary, Func):
5031    arg_types = {"this": True, "expression": True, "null_if_invalid": False}
5032    _sql_names = ["JSON_EXTRACT_SCALAR"]
5033
5034    @property
5035    def output_name(self) -> str:
5036        return self.expression.output_name
5037
5038
5039class JSONBExtract(Binary, Func):
5040    _sql_names = ["JSONB_EXTRACT"]
5041
5042
5043class JSONBExtractScalar(Binary, Func):
5044    _sql_names = ["JSONB_EXTRACT_SCALAR"]
5045
5046
5047class JSONFormat(Func):
5048    arg_types = {"this": False, "options": False}
5049    _sql_names = ["JSON_FORMAT"]
5050
5051
5052# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
5053class JSONArrayContains(Binary, Predicate, Func):
5054    _sql_names = ["JSON_ARRAY_CONTAINS"]
5055
5056
5057class ParseJSON(Func):
5058    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5059    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5060    arg_types = {"this": True, "expressions": False}
5061    is_var_len_args = True
5062
5063
5064class Least(Func):
5065    arg_types = {"this": True, "expressions": False}
5066    is_var_len_args = True
5067
5068
5069class Left(Func):
5070    arg_types = {"this": True, "expression": True}
5071
5072
5073class Right(Func):
5074    arg_types = {"this": True, "expression": True}
5075
5076
5077class Length(Func):
5078    _sql_names = ["LENGTH", "LEN"]
5079
5080
5081class Levenshtein(Func):
5082    arg_types = {
5083        "this": True,
5084        "expression": False,
5085        "ins_cost": False,
5086        "del_cost": False,
5087        "sub_cost": False,
5088    }
5089
5090
5091class Ln(Func):
5092    pass
5093
5094
5095class Log(Func):
5096    arg_types = {"this": True, "expression": False}
5097
5098
5099class Log2(Func):
5100    pass
5101
5102
5103class Log10(Func):
5104    pass
5105
5106
5107class LogicalOr(AggFunc):
5108    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
5109
5110
5111class LogicalAnd(AggFunc):
5112    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
5113
5114
5115class Lower(Func):
5116    _sql_names = ["LOWER", "LCASE"]
5117
5118
5119class Map(Func):
5120    arg_types = {"keys": False, "values": False}
5121
5122    @property
5123    def keys(self) -> t.List[Expression]:
5124        keys = self.args.get("keys")
5125        return keys.expressions if keys else []
5126
5127    @property
5128    def values(self) -> t.List[Expression]:
5129        values = self.args.get("values")
5130        return values.expressions if values else []
5131
5132
5133class MapFromEntries(Func):
5134    pass
5135
5136
5137class StarMap(Func):
5138    pass
5139
5140
5141class VarMap(Func):
5142    arg_types = {"keys": True, "values": True}
5143    is_var_len_args = True
5144
5145    @property
5146    def keys(self) -> t.List[Expression]:
5147        return self.args["keys"].expressions
5148
5149    @property
5150    def values(self) -> t.List[Expression]:
5151        return self.args["values"].expressions
5152
5153
5154# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
5155class MatchAgainst(Func):
5156    arg_types = {"this": True, "expressions": True, "modifier": False}
5157
5158
5159class Max(AggFunc):
5160    arg_types = {"this": True, "expressions": False}
5161    is_var_len_args = True
5162
5163
5164class MD5(Func):
5165    _sql_names = ["MD5"]
5166
5167
5168# Represents the variant of the MD5 function that returns a binary value
5169class MD5Digest(Func):
5170    _sql_names = ["MD5_DIGEST"]
5171
5172
5173class Min(AggFunc):
5174    arg_types = {"this": True, "expressions": False}
5175    is_var_len_args = True
5176
5177
5178class Month(Func):
5179    pass
5180
5181
5182class Nvl2(Func):
5183    arg_types = {"this": True, "true": True, "false": False}
5184
5185
5186# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5187class Predict(Func):
5188    arg_types = {"this": True, "expression": True, "params_struct": False}
5189
5190
5191class Pow(Binary, Func):
5192    _sql_names = ["POWER", "POW"]
5193
5194
5195class PercentileCont(AggFunc):
5196    arg_types = {"this": True, "expression": False}
5197
5198
5199class PercentileDisc(AggFunc):
5200    arg_types = {"this": True, "expression": False}
5201
5202
5203class Quantile(AggFunc):
5204    arg_types = {"this": True, "quantile": True}
5205
5206
5207class ApproxQuantile(Quantile):
5208    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5209
5210
5211class Rand(Func):
5212    _sql_names = ["RAND", "RANDOM"]
5213    arg_types = {"this": False}
5214
5215
5216class Randn(Func):
5217    arg_types = {"this": False}
5218
5219
5220class RangeN(Func):
5221    arg_types = {"this": True, "expressions": True, "each": False}
5222
5223
5224class ReadCSV(Func):
5225    _sql_names = ["READ_CSV"]
5226    is_var_len_args = True
5227    arg_types = {"this": True, "expressions": False}
5228
5229
5230class Reduce(Func):
5231    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5232
5233
5234class RegexpExtract(Func):
5235    arg_types = {
5236        "this": True,
5237        "expression": True,
5238        "position": False,
5239        "occurrence": False,
5240        "parameters": False,
5241        "group": False,
5242    }
5243
5244
5245class RegexpReplace(Func):
5246    arg_types = {
5247        "this": True,
5248        "expression": True,
5249        "replacement": False,
5250        "position": False,
5251        "occurrence": False,
5252        "parameters": False,
5253        "modifiers": False,
5254    }
5255
5256
5257class RegexpLike(Binary, Func):
5258    arg_types = {"this": True, "expression": True, "flag": False}
5259
5260
5261class RegexpILike(Binary, Func):
5262    arg_types = {"this": True, "expression": True, "flag": False}
5263
5264
5265# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5266# limit is the number of times a pattern is applied
5267class RegexpSplit(Func):
5268    arg_types = {"this": True, "expression": True, "limit": False}
5269
5270
5271class Repeat(Func):
5272    arg_types = {"this": True, "times": True}
5273
5274
5275# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
5276# tsql third argument function == trunctaion if not 0
5277class Round(Func):
5278    arg_types = {"this": True, "decimals": False, "truncate": False}
5279
5280
5281class RowNumber(Func):
5282    arg_types: t.Dict[str, t.Any] = {}
5283
5284
5285class SafeDivide(Func):
5286    arg_types = {"this": True, "expression": True}
5287
5288
5289class SHA(Func):
5290    _sql_names = ["SHA", "SHA1"]
5291
5292
5293class SHA2(Func):
5294    _sql_names = ["SHA2"]
5295    arg_types = {"this": True, "length": False}
5296
5297
5298class SortArray(Func):
5299    arg_types = {"this": True, "asc": False}
5300
5301
5302class Split(Func):
5303    arg_types = {"this": True, "expression": True, "limit": False}
5304
5305
5306# Start may be omitted in the case of postgres
5307# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5308class Substring(Func):
5309    arg_types = {"this": True, "start": False, "length": False}
5310
5311
5312class StandardHash(Func):
5313    arg_types = {"this": True, "expression": False}
5314
5315
5316class StartsWith(Func):
5317    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5318    arg_types = {"this": True, "expression": True}
5319
5320
5321class StrPosition(Func):
5322    arg_types = {
5323        "this": True,
5324        "substr": True,
5325        "position": False,
5326        "instance": False,
5327    }
5328
5329
5330class StrToDate(Func):
5331    arg_types = {"this": True, "format": True}
5332
5333
5334class StrToTime(Func):
5335    arg_types = {"this": True, "format": True, "zone": False}
5336
5337
5338# Spark allows unix_timestamp()
5339# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5340class StrToUnix(Func):
5341    arg_types = {"this": False, "format": False}
5342
5343
5344# https://prestodb.io/docs/current/functions/string.html
5345# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5346class StrToMap(Func):
5347    arg_types = {
5348        "this": True,
5349        "pair_delim": False,
5350        "key_value_delim": False,
5351        "duplicate_resolution_callback": False,
5352    }
5353
5354
5355class NumberToStr(Func):
5356    arg_types = {"this": True, "format": True, "culture": False}
5357
5358
5359class FromBase(Func):
5360    arg_types = {"this": True, "expression": True}
5361
5362
5363class Struct(Func):
5364    arg_types = {"expressions": False}
5365    is_var_len_args = True
5366
5367
5368class StructExtract(Func):
5369    arg_types = {"this": True, "expression": True}
5370
5371
5372# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5373# https://docs.snowflake.com/en/sql-reference/functions/insert
5374class Stuff(Func):
5375    _sql_names = ["STUFF", "INSERT"]
5376    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5377
5378
5379class Sum(AggFunc):
5380    pass
5381
5382
5383class Sqrt(Func):
5384    pass
5385
5386
5387class Stddev(AggFunc):
5388    pass
5389
5390
5391class StddevPop(AggFunc):
5392    pass
5393
5394
5395class StddevSamp(AggFunc):
5396    pass
5397
5398
5399class TimeToStr(Func):
5400    arg_types = {"this": True, "format": True, "culture": False}
5401
5402
5403class TimeToTimeStr(Func):
5404    pass
5405
5406
5407class TimeToUnix(Func):
5408    pass
5409
5410
5411class TimeStrToDate(Func):
5412    pass
5413
5414
5415class TimeStrToTime(Func):
5416    pass
5417
5418
5419class TimeStrToUnix(Func):
5420    pass
5421
5422
5423class Trim(Func):
5424    arg_types = {
5425        "this": True,
5426        "expression": False,
5427        "position": False,
5428        "collation": False,
5429    }
5430
5431
5432class TsOrDsAdd(Func, TimeUnit):
5433    # return_type is used to correctly cast the arguments of this expression when transpiling it
5434    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5435
5436    @property
5437    def return_type(self) -> DataType:
5438        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5439
5440
5441class TsOrDsDiff(Func, TimeUnit):
5442    arg_types = {"this": True, "expression": True, "unit": False}
5443
5444
5445class TsOrDsToDateStr(Func):
5446    pass
5447
5448
5449class TsOrDsToDate(Func):
5450    arg_types = {"this": True, "format": False}
5451
5452
5453class TsOrDsToTime(Func):
5454    pass
5455
5456
5457class TsOrDiToDi(Func):
5458    pass
5459
5460
5461class Unhex(Func):
5462    pass
5463
5464
5465# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
5466class UnixDate(Func):
5467    pass
5468
5469
5470class UnixToStr(Func):
5471    arg_types = {"this": True, "format": False}
5472
5473
5474# https://prestodb.io/docs/current/functions/datetime.html
5475# presto has weird zone/hours/minutes
5476class UnixToTime(Func):
5477    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5478
5479    SECONDS = Literal.number(0)
5480    DECIS = Literal.number(1)
5481    CENTIS = Literal.number(2)
5482    MILLIS = Literal.number(3)
5483    DECIMILLIS = Literal.number(4)
5484    CENTIMILLIS = Literal.number(5)
5485    MICROS = Literal.number(6)
5486    DECIMICROS = Literal.number(7)
5487    CENTIMICROS = Literal.number(8)
5488    NANOS = Literal.number(9)
5489
5490
5491class UnixToTimeStr(Func):
5492    pass
5493
5494
5495class TimestampFromParts(Func):
5496    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5497    arg_types = {
5498        "year": True,
5499        "month": True,
5500        "day": True,
5501        "hour": True,
5502        "min": True,
5503        "sec": True,
5504        "nano": False,
5505        "zone": False,
5506        "milli": False,
5507    }
5508
5509
5510class Upper(Func):
5511    _sql_names = ["UPPER", "UCASE"]
5512
5513
5514class Variance(AggFunc):
5515    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5516
5517
5518class VariancePop(AggFunc):
5519    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5520
5521
5522class Week(Func):
5523    arg_types = {"this": True, "mode": False}
5524
5525
5526class XMLTable(Func):
5527    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5528
5529
5530class Year(Func):
5531    pass
5532
5533
5534class Use(Expression):
5535    arg_types = {"this": True, "kind": False}
5536
5537
5538class Merge(Expression):
5539    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
5540
5541
5542class When(Func):
5543    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5544
5545
5546# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5547# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5548class NextValueFor(Func):
5549    arg_types = {"this": True, "order": False}
5550
5551
5552def _norm_arg(arg):
5553    return arg.lower() if type(arg) is str else arg
5554
5555
5556ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5557FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
5558
5559JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
5560
5561
5562# Helpers
5563@t.overload
5564def maybe_parse(
5565    sql_or_expression: ExpOrStr,
5566    *,
5567    into: t.Type[E],
5568    dialect: DialectType = None,
5569    prefix: t.Optional[str] = None,
5570    copy: bool = False,
5571    **opts,
5572) -> E:
5573    ...
5574
5575
5576@t.overload
5577def maybe_parse(
5578    sql_or_expression: str | E,
5579    *,
5580    into: t.Optional[IntoType] = None,
5581    dialect: DialectType = None,
5582    prefix: t.Optional[str] = None,
5583    copy: bool = False,
5584    **opts,
5585) -> E:
5586    ...
5587
5588
5589def maybe_parse(
5590    sql_or_expression: ExpOrStr,
5591    *,
5592    into: t.Optional[IntoType] = None,
5593    dialect: DialectType = None,
5594    prefix: t.Optional[str] = None,
5595    copy: bool = False,
5596    **opts,
5597) -> Expression:
5598    """Gracefully handle a possible string or expression.
5599
5600    Example:
5601        >>> maybe_parse("1")
5602        Literal(this=1, is_string=False)
5603        >>> maybe_parse(to_identifier("x"))
5604        Identifier(this=x, quoted=False)
5605
5606    Args:
5607        sql_or_expression: the SQL code string or an expression
5608        into: the SQLGlot Expression to parse into
5609        dialect: the dialect used to parse the input expressions (in the case that an
5610            input expression is a SQL string).
5611        prefix: a string to prefix the sql with before it gets parsed
5612            (automatically includes a space)
5613        copy: whether or not to copy the expression.
5614        **opts: other options to use to parse the input expressions (again, in the case
5615            that an input expression is a SQL string).
5616
5617    Returns:
5618        Expression: the parsed or given expression.
5619    """
5620    if isinstance(sql_or_expression, Expression):
5621        if copy:
5622            return sql_or_expression.copy()
5623        return sql_or_expression
5624
5625    if sql_or_expression is None:
5626        raise ParseError("SQL cannot be None")
5627
5628    import sqlglot
5629
5630    sql = str(sql_or_expression)
5631    if prefix:
5632        sql = f"{prefix} {sql}"
5633
5634    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5635
5636
5637@t.overload
5638def maybe_copy(instance: None, copy: bool = True) -> None:
5639    ...
5640
5641
5642@t.overload
5643def maybe_copy(instance: E, copy: bool = True) -> E:
5644    ...
5645
5646
5647def maybe_copy(instance, copy=True):
5648    return instance.copy() if copy and instance else instance
5649
5650
5651def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
5652    """Generate a textual representation of an Expression tree"""
5653    indent = "\n" + ("  " * (level + 1))
5654    delim = f",{indent}"
5655
5656    if isinstance(node, Expression):
5657        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
5658
5659        if (node.type or verbose) and not isinstance(node, DataType):
5660            args["_type"] = node.type
5661        if node.comments or verbose:
5662            args["_comments"] = node.comments
5663
5664        if verbose:
5665            args["_id"] = id(node)
5666
5667        # Inline leaves for a more compact representation
5668        if node.is_leaf():
5669            indent = ""
5670            delim = ", "
5671
5672        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
5673        return f"{node.__class__.__name__}({indent}{items})"
5674
5675    if isinstance(node, list):
5676        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
5677        items = f"{indent}{items}" if items else ""
5678        return f"[{items}]"
5679
5680    # Indent multiline strings to match the current level
5681    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
5682
5683
5684def _is_wrong_expression(expression, into):
5685    return isinstance(expression, Expression) and not isinstance(expression, into)
5686
5687
5688def _apply_builder(
5689    expression,
5690    instance,
5691    arg,
5692    copy=True,
5693    prefix=None,
5694    into=None,
5695    dialect=None,
5696    into_arg="this",
5697    **opts,
5698):
5699    if _is_wrong_expression(expression, into):
5700        expression = into(**{into_arg: expression})
5701    instance = maybe_copy(instance, copy)
5702    expression = maybe_parse(
5703        sql_or_expression=expression,
5704        prefix=prefix,
5705        into=into,
5706        dialect=dialect,
5707        **opts,
5708    )
5709    instance.set(arg, expression)
5710    return instance
5711
5712
5713def _apply_child_list_builder(
5714    *expressions,
5715    instance,
5716    arg,
5717    append=True,
5718    copy=True,
5719    prefix=None,
5720    into=None,
5721    dialect=None,
5722    properties=None,
5723    **opts,
5724):
5725    instance = maybe_copy(instance, copy)
5726    parsed = []
5727    for expression in expressions:
5728        if expression is not None:
5729            if _is_wrong_expression(expression, into):
5730                expression = into(expressions=[expression])
5731
5732            expression = maybe_parse(
5733                expression,
5734                into=into,
5735                dialect=dialect,
5736                prefix=prefix,
5737                **opts,
5738            )
5739            parsed.extend(expression.expressions)
5740
5741    existing = instance.args.get(arg)
5742    if append and existing:
5743        parsed = existing.expressions + parsed
5744
5745    child = into(expressions=parsed)
5746    for k, v in (properties or {}).items():
5747        child.set(k, v)
5748    instance.set(arg, child)
5749
5750    return instance
5751
5752
5753def _apply_list_builder(
5754    *expressions,
5755    instance,
5756    arg,
5757    append=True,
5758    copy=True,
5759    prefix=None,
5760    into=None,
5761    dialect=None,
5762    **opts,
5763):
5764    inst = maybe_copy(instance, copy)
5765
5766    expressions = [
5767        maybe_parse(
5768            sql_or_expression=expression,
5769            into=into,
5770            prefix=prefix,
5771            dialect=dialect,
5772            **opts,
5773        )
5774        for expression in expressions
5775        if expression is not None
5776    ]
5777
5778    existing_expressions = inst.args.get(arg)
5779    if append and existing_expressions:
5780        expressions = existing_expressions + expressions
5781
5782    inst.set(arg, expressions)
5783    return inst
5784
5785
5786def _apply_conjunction_builder(
5787    *expressions,
5788    instance,
5789    arg,
5790    into=None,
5791    append=True,
5792    copy=True,
5793    dialect=None,
5794    **opts,
5795):
5796    expressions = [exp for exp in expressions if exp is not None and exp != ""]
5797    if not expressions:
5798        return instance
5799
5800    inst = maybe_copy(instance, copy)
5801
5802    existing = inst.args.get(arg)
5803    if append and existing is not None:
5804        expressions = [existing.this if into else existing] + list(expressions)
5805
5806    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
5807
5808    inst.set(arg, into(this=node) if into else node)
5809    return inst
5810
5811
5812def _apply_cte_builder(
5813    instance: E,
5814    alias: ExpOrStr,
5815    as_: ExpOrStr,
5816    recursive: t.Optional[bool] = None,
5817    append: bool = True,
5818    dialect: DialectType = None,
5819    copy: bool = True,
5820    **opts,
5821) -> E:
5822    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
5823    as_expression = maybe_parse(as_, dialect=dialect, **opts)
5824    cte = CTE(this=as_expression, alias=alias_expression)
5825    return _apply_child_list_builder(
5826        cte,
5827        instance=instance,
5828        arg="with",
5829        append=append,
5830        copy=copy,
5831        into=With,
5832        properties={"recursive": recursive or False},
5833    )
5834
5835
5836def _combine(
5837    expressions: t.Sequence[t.Optional[ExpOrStr]],
5838    operator: t.Type[Connector],
5839    dialect: DialectType = None,
5840    copy: bool = True,
5841    **opts,
5842) -> Expression:
5843    conditions = [
5844        condition(expression, dialect=dialect, copy=copy, **opts)
5845        for expression in expressions
5846        if expression is not None
5847    ]
5848
5849    this, *rest = conditions
5850    if rest:
5851        this = _wrap(this, Connector)
5852    for expression in rest:
5853        this = operator(this=this, expression=_wrap(expression, Connector))
5854
5855    return this
5856
5857
5858def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
5859    return Paren(this=expression) if isinstance(expression, kind) else expression
5860
5861
5862def union(
5863    left: ExpOrStr,
5864    right: ExpOrStr,
5865    distinct: bool = True,
5866    dialect: DialectType = None,
5867    copy: bool = True,
5868    **opts,
5869) -> Union:
5870    """
5871    Initializes a syntax tree from one UNION expression.
5872
5873    Example:
5874        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5875        'SELECT * FROM foo UNION SELECT * FROM bla'
5876
5877    Args:
5878        left: the SQL code string corresponding to the left-hand side.
5879            If an `Expression` instance is passed, it will be used as-is.
5880        right: the SQL code string corresponding to the right-hand side.
5881            If an `Expression` instance is passed, it will be used as-is.
5882        distinct: set the DISTINCT flag if and only if this is true.
5883        dialect: the dialect used to parse the input expression.
5884        copy: whether or not to copy the expression.
5885        opts: other options to use to parse the input expressions.
5886
5887    Returns:
5888        The new Union instance.
5889    """
5890    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5891    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5892
5893    return Union(this=left, expression=right, distinct=distinct)
5894
5895
5896def intersect(
5897    left: ExpOrStr,
5898    right: ExpOrStr,
5899    distinct: bool = True,
5900    dialect: DialectType = None,
5901    copy: bool = True,
5902    **opts,
5903) -> Intersect:
5904    """
5905    Initializes a syntax tree from one INTERSECT expression.
5906
5907    Example:
5908        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5909        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5910
5911    Args:
5912        left: the SQL code string corresponding to the left-hand side.
5913            If an `Expression` instance is passed, it will be used as-is.
5914        right: the SQL code string corresponding to the right-hand side.
5915            If an `Expression` instance is passed, it will be used as-is.
5916        distinct: set the DISTINCT flag if and only if this is true.
5917        dialect: the dialect used to parse the input expression.
5918        copy: whether or not to copy the expression.
5919        opts: other options to use to parse the input expressions.
5920
5921    Returns:
5922        The new Intersect instance.
5923    """
5924    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5925    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5926
5927    return Intersect(this=left, expression=right, distinct=distinct)
5928
5929
5930def except_(
5931    left: ExpOrStr,
5932    right: ExpOrStr,
5933    distinct: bool = True,
5934    dialect: DialectType = None,
5935    copy: bool = True,
5936    **opts,
5937) -> Except:
5938    """
5939    Initializes a syntax tree from one EXCEPT expression.
5940
5941    Example:
5942        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5943        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5944
5945    Args:
5946        left: the SQL code string corresponding to the left-hand side.
5947            If an `Expression` instance is passed, it will be used as-is.
5948        right: the SQL code string corresponding to the right-hand side.
5949            If an `Expression` instance is passed, it will be used as-is.
5950        distinct: set the DISTINCT flag if and only if this is true.
5951        dialect: the dialect used to parse the input expression.
5952        copy: whether or not to copy the expression.
5953        opts: other options to use to parse the input expressions.
5954
5955    Returns:
5956        The new Except instance.
5957    """
5958    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5959    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5960
5961    return Except(this=left, expression=right, distinct=distinct)
5962
5963
5964def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5965    """
5966    Initializes a syntax tree from one or multiple SELECT expressions.
5967
5968    Example:
5969        >>> select("col1", "col2").from_("tbl").sql()
5970        'SELECT col1, col2 FROM tbl'
5971
5972    Args:
5973        *expressions: the SQL code string to parse as the expressions of a
5974            SELECT statement. If an Expression instance is passed, this is used as-is.
5975        dialect: the dialect used to parse the input expressions (in the case that an
5976            input expression is a SQL string).
5977        **opts: other options to use to parse the input expressions (again, in the case
5978            that an input expression is a SQL string).
5979
5980    Returns:
5981        Select: the syntax tree for the SELECT statement.
5982    """
5983    return Select().select(*expressions, dialect=dialect, **opts)
5984
5985
5986def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5987    """
5988    Initializes a syntax tree from a FROM expression.
5989
5990    Example:
5991        >>> from_("tbl").select("col1", "col2").sql()
5992        'SELECT col1, col2 FROM tbl'
5993
5994    Args:
5995        *expression: the SQL code string to parse as the FROM expressions of a
5996            SELECT statement. If an Expression instance is passed, this is used as-is.
5997        dialect: the dialect used to parse the input expression (in the case that the
5998            input expression is a SQL string).
5999        **opts: other options to use to parse the input expressions (again, in the case
6000            that the input expression is a SQL string).
6001
6002    Returns:
6003        Select: the syntax tree for the SELECT statement.
6004    """
6005    return Select().from_(expression, dialect=dialect, **opts)
6006
6007
6008def update(
6009    table: str | Table,
6010    properties: dict,
6011    where: t.Optional[ExpOrStr] = None,
6012    from_: t.Optional[ExpOrStr] = None,
6013    dialect: DialectType = None,
6014    **opts,
6015) -> Update:
6016    """
6017    Creates an update statement.
6018
6019    Example:
6020        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6021        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6022
6023    Args:
6024        *properties: dictionary of properties to set which are
6025            auto converted to sql objects eg None -> NULL
6026        where: sql conditional parsed into a WHERE statement
6027        from_: sql statement parsed into a FROM statement
6028        dialect: the dialect used to parse the input expressions.
6029        **opts: other options to use to parse the input expressions.
6030
6031    Returns:
6032        Update: the syntax tree for the UPDATE statement.
6033    """
6034    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6035    update_expr.set(
6036        "expressions",
6037        [
6038            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6039            for k, v in properties.items()
6040        ],
6041    )
6042    if from_:
6043        update_expr.set(
6044            "from",
6045            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6046        )
6047    if isinstance(where, Condition):
6048        where = Where(this=where)
6049    if where:
6050        update_expr.set(
6051            "where",
6052            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6053        )
6054    return update_expr
6055
6056
6057def delete(
6058    table: ExpOrStr,
6059    where: t.Optional[ExpOrStr] = None,
6060    returning: t.Optional[ExpOrStr] = None,
6061    dialect: DialectType = None,
6062    **opts,
6063) -> Delete:
6064    """
6065    Builds a delete statement.
6066
6067    Example:
6068        >>> delete("my_table", where="id > 1").sql()
6069        'DELETE FROM my_table WHERE id > 1'
6070
6071    Args:
6072        where: sql conditional parsed into a WHERE statement
6073        returning: sql conditional parsed into a RETURNING statement
6074        dialect: the dialect used to parse the input expressions.
6075        **opts: other options to use to parse the input expressions.
6076
6077    Returns:
6078        Delete: the syntax tree for the DELETE statement.
6079    """
6080    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6081    if where:
6082        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6083    if returning:
6084        delete_expr = t.cast(
6085            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6086        )
6087    return delete_expr
6088
6089
6090def insert(
6091    expression: ExpOrStr,
6092    into: ExpOrStr,
6093    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6094    overwrite: t.Optional[bool] = None,
6095    returning: t.Optional[ExpOrStr] = None,
6096    dialect: DialectType = None,
6097    copy: bool = True,
6098    **opts,
6099) -> Insert:
6100    """
6101    Builds an INSERT statement.
6102
6103    Example:
6104        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6105        'INSERT INTO tbl VALUES (1, 2, 3)'
6106
6107    Args:
6108        expression: the sql string or expression of the INSERT statement
6109        into: the tbl to insert data to.
6110        columns: optionally the table's column names.
6111        overwrite: whether to INSERT OVERWRITE or not.
6112        returning: sql conditional parsed into a RETURNING statement
6113        dialect: the dialect used to parse the input expressions.
6114        copy: whether or not to copy the expression.
6115        **opts: other options to use to parse the input expressions.
6116
6117    Returns:
6118        Insert: the syntax tree for the INSERT statement.
6119    """
6120    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6121    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6122
6123    if columns:
6124        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6125
6126    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6127
6128    if returning:
6129        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6130
6131    return insert
6132
6133
6134def condition(
6135    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6136) -> Condition:
6137    """
6138    Initialize a logical condition expression.
6139
6140    Example:
6141        >>> condition("x=1").sql()
6142        'x = 1'
6143
6144        This is helpful for composing larger logical syntax trees:
6145        >>> where = condition("x=1")
6146        >>> where = where.and_("y=1")
6147        >>> Select().from_("tbl").select("*").where(where).sql()
6148        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6149
6150    Args:
6151        *expression: the SQL code string to parse.
6152            If an Expression instance is passed, this is used as-is.
6153        dialect: the dialect used to parse the input expression (in the case that the
6154            input expression is a SQL string).
6155        copy: Whether or not to copy `expression` (only applies to expressions).
6156        **opts: other options to use to parse the input expressions (again, in the case
6157            that the input expression is a SQL string).
6158
6159    Returns:
6160        The new Condition instance
6161    """
6162    return maybe_parse(
6163        expression,
6164        into=Condition,
6165        dialect=dialect,
6166        copy=copy,
6167        **opts,
6168    )
6169
6170
6171def and_(
6172    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6173) -> Condition:
6174    """
6175    Combine multiple conditions with an AND logical operator.
6176
6177    Example:
6178        >>> and_("x=1", and_("y=1", "z=1")).sql()
6179        'x = 1 AND (y = 1 AND z = 1)'
6180
6181    Args:
6182        *expressions: the SQL code strings to parse.
6183            If an Expression instance is passed, this is used as-is.
6184        dialect: the dialect used to parse the input expression.
6185        copy: whether or not to copy `expressions` (only applies to Expressions).
6186        **opts: other options to use to parse the input expressions.
6187
6188    Returns:
6189        And: the new condition
6190    """
6191    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
6192
6193
6194def or_(
6195    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6196) -> Condition:
6197    """
6198    Combine multiple conditions with an OR logical operator.
6199
6200    Example:
6201        >>> or_("x=1", or_("y=1", "z=1")).sql()
6202        'x = 1 OR (y = 1 OR z = 1)'
6203
6204    Args:
6205        *expressions: the SQL code strings to parse.
6206            If an Expression instance is passed, this is used as-is.
6207        dialect: the dialect used to parse the input expression.
6208        copy: whether or not to copy `expressions` (only applies to Expressions).
6209        **opts: other options to use to parse the input expressions.
6210
6211    Returns:
6212        Or: the new condition
6213    """
6214    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
6215
6216
6217def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6218    """
6219    Wrap a condition with a NOT operator.
6220
6221    Example:
6222        >>> not_("this_suit='black'").sql()
6223        "NOT this_suit = 'black'"
6224
6225    Args:
6226        expression: the SQL code string to parse.
6227            If an Expression instance is passed, this is used as-is.
6228        dialect: the dialect used to parse the input expression.
6229        copy: whether to copy the expression or not.
6230        **opts: other options to use to parse the input expressions.
6231
6232    Returns:
6233        The new condition.
6234    """
6235    this = condition(
6236        expression,
6237        dialect=dialect,
6238        copy=copy,
6239        **opts,
6240    )
6241    return Not(this=_wrap(this, Connector))
6242
6243
6244def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6245    """
6246    Wrap an expression in parentheses.
6247
6248    Example:
6249        >>> paren("5 + 3").sql()
6250        '(5 + 3)'
6251
6252    Args:
6253        expression: the SQL code string to parse.
6254            If an Expression instance is passed, this is used as-is.
6255        copy: whether to copy the expression or not.
6256
6257    Returns:
6258        The wrapped expression.
6259    """
6260    return Paren(this=maybe_parse(expression, copy=copy))
6261
6262
6263SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
6264
6265
6266@t.overload
6267def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None:
6268    ...
6269
6270
6271@t.overload
6272def to_identifier(
6273    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
6274) -> Identifier:
6275    ...
6276
6277
6278def to_identifier(name, quoted=None, copy=True):
6279    """Builds an identifier.
6280
6281    Args:
6282        name: The name to turn into an identifier.
6283        quoted: Whether or not force quote the identifier.
6284        copy: Whether or not to copy name if it's an Identifier.
6285
6286    Returns:
6287        The identifier ast node.
6288    """
6289
6290    if name is None:
6291        return None
6292
6293    if isinstance(name, Identifier):
6294        identifier = maybe_copy(name, copy)
6295    elif isinstance(name, str):
6296        identifier = Identifier(
6297            this=name,
6298            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6299        )
6300    else:
6301        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6302    return identifier
6303
6304
6305def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6306    """
6307    Parses a given string into an identifier.
6308
6309    Args:
6310        name: The name to parse into an identifier.
6311        dialect: The dialect to parse against.
6312
6313    Returns:
6314        The identifier ast node.
6315    """
6316    try:
6317        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6318    except ParseError:
6319        expression = to_identifier(name)
6320
6321    return expression
6322
6323
6324INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6325
6326
6327def to_interval(interval: str | Literal) -> Interval:
6328    """Builds an interval expression from a string like '1 day' or '5 months'."""
6329    if isinstance(interval, Literal):
6330        if not interval.is_string:
6331            raise ValueError("Invalid interval string.")
6332
6333        interval = interval.this
6334
6335    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6336
6337    if not interval_parts:
6338        raise ValueError("Invalid interval string.")
6339
6340    return Interval(
6341        this=Literal.string(interval_parts.group(1)),
6342        unit=Var(this=interval_parts.group(2).upper()),
6343    )
6344
6345
6346@t.overload
6347def to_table(sql_path: str | Table, **kwargs) -> Table:
6348    ...
6349
6350
6351@t.overload
6352def to_table(sql_path: None, **kwargs) -> None:
6353    ...
6354
6355
6356def to_table(
6357    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6358) -> t.Optional[Table]:
6359    """
6360    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6361    If a table is passed in then that table is returned.
6362
6363    Args:
6364        sql_path: a `[catalog].[schema].[table]` string.
6365        dialect: the source dialect according to which the table name will be parsed.
6366        copy: Whether or not to copy a table if it is passed in.
6367        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6368
6369    Returns:
6370        A table expression.
6371    """
6372    if sql_path is None or isinstance(sql_path, Table):
6373        return maybe_copy(sql_path, copy=copy)
6374    if not isinstance(sql_path, str):
6375        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6376
6377    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6378    if table:
6379        for k, v in kwargs.items():
6380            table.set(k, v)
6381
6382    return table
6383
6384
6385def to_column(sql_path: str | Column, **kwargs) -> Column:
6386    """
6387    Create a column from a `[table].[column]` sql path. Schema is optional.
6388
6389    If a column is passed in then that column is returned.
6390
6391    Args:
6392        sql_path: `[table].[column]` string
6393    Returns:
6394        Table: A column expression
6395    """
6396    if sql_path is None or isinstance(sql_path, Column):
6397        return sql_path
6398    if not isinstance(sql_path, str):
6399        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6400    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
6401
6402
6403def alias_(
6404    expression: ExpOrStr,
6405    alias: str | Identifier,
6406    table: bool | t.Sequence[str | Identifier] = False,
6407    quoted: t.Optional[bool] = None,
6408    dialect: DialectType = None,
6409    copy: bool = True,
6410    **opts,
6411):
6412    """Create an Alias expression.
6413
6414    Example:
6415        >>> alias_('foo', 'bar').sql()
6416        'foo AS bar'
6417
6418        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6419        '(SELECT 1, 2) AS bar(a, b)'
6420
6421    Args:
6422        expression: the SQL code strings to parse.
6423            If an Expression instance is passed, this is used as-is.
6424        alias: the alias name to use. If the name has
6425            special characters it is quoted.
6426        table: Whether or not to create a table alias, can also be a list of columns.
6427        quoted: whether or not to quote the alias
6428        dialect: the dialect used to parse the input expression.
6429        copy: Whether or not to copy the expression.
6430        **opts: other options to use to parse the input expressions.
6431
6432    Returns:
6433        Alias: the aliased expression
6434    """
6435    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6436    alias = to_identifier(alias, quoted=quoted)
6437
6438    if table:
6439        table_alias = TableAlias(this=alias)
6440        exp.set("alias", table_alias)
6441
6442        if not isinstance(table, bool):
6443            for column in table:
6444                table_alias.append("columns", to_identifier(column, quoted=quoted))
6445
6446        return exp
6447
6448    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6449    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6450    # for the complete Window expression.
6451    #
6452    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6453
6454    if "alias" in exp.arg_types and not isinstance(exp, Window):
6455        exp.set("alias", alias)
6456        return exp
6457    return Alias(this=exp, alias=alias)
6458
6459
6460def subquery(
6461    expression: ExpOrStr,
6462    alias: t.Optional[Identifier | str] = None,
6463    dialect: DialectType = None,
6464    **opts,
6465) -> Select:
6466    """
6467    Build a subquery expression.
6468
6469    Example:
6470        >>> subquery('select x from tbl', 'bar').select('x').sql()
6471        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6472
6473    Args:
6474        expression: the SQL code strings to parse.
6475            If an Expression instance is passed, this is used as-is.
6476        alias: the alias name to use.
6477        dialect: the dialect used to parse the input expression.
6478        **opts: other options to use to parse the input expressions.
6479
6480    Returns:
6481        A new Select instance with the subquery expression included.
6482    """
6483
6484    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6485    return Select().from_(expression, dialect=dialect, **opts)
6486
6487
6488@t.overload
6489def column(
6490    col: str | Identifier,
6491    table: t.Optional[str | Identifier] = None,
6492    db: t.Optional[str | Identifier] = None,
6493    catalog: t.Optional[str | Identifier] = None,
6494    *,
6495    fields: t.Collection[t.Union[str, Identifier]],
6496    quoted: t.Optional[bool] = None,
6497    copy: bool = True,
6498) -> Dot:
6499    pass
6500
6501
6502@t.overload
6503def column(
6504    col: str | Identifier,
6505    table: t.Optional[str | Identifier] = None,
6506    db: t.Optional[str | Identifier] = None,
6507    catalog: t.Optional[str | Identifier] = None,
6508    *,
6509    fields: Lit[None] = None,
6510    quoted: t.Optional[bool] = None,
6511    copy: bool = True,
6512) -> Column:
6513    pass
6514
6515
6516def column(
6517    col,
6518    table=None,
6519    db=None,
6520    catalog=None,
6521    *,
6522    fields=None,
6523    quoted=None,
6524    copy=True,
6525):
6526    """
6527    Build a Column.
6528
6529    Args:
6530        col: Column name.
6531        table: Table name.
6532        db: Database name.
6533        catalog: Catalog name.
6534        fields: Additional fields using dots.
6535        quoted: Whether to force quotes on the column's identifiers.
6536        copy: Whether or not to copy identifiers if passed in.
6537
6538    Returns:
6539        The new Column instance.
6540    """
6541    this = Column(
6542        this=to_identifier(col, quoted=quoted, copy=copy),
6543        table=to_identifier(table, quoted=quoted, copy=copy),
6544        db=to_identifier(db, quoted=quoted, copy=copy),
6545        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6546    )
6547
6548    if fields:
6549        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6550    return this
6551
6552
6553def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6554    """Cast an expression to a data type.
6555
6556    Example:
6557        >>> cast('x + 1', 'int').sql()
6558        'CAST(x + 1 AS INT)'
6559
6560    Args:
6561        expression: The expression to cast.
6562        to: The datatype to cast to.
6563        copy: Whether or not to copy the supplied expressions.
6564
6565    Returns:
6566        The new Cast instance.
6567    """
6568    expression = maybe_parse(expression, copy=copy, **opts)
6569    data_type = DataType.build(to, copy=copy, **opts)
6570    expression = Cast(this=expression, to=data_type)
6571    expression.type = data_type
6572    return expression
6573
6574
6575def table_(
6576    table: Identifier | str,
6577    db: t.Optional[Identifier | str] = None,
6578    catalog: t.Optional[Identifier | str] = None,
6579    quoted: t.Optional[bool] = None,
6580    alias: t.Optional[Identifier | str] = None,
6581) -> Table:
6582    """Build a Table.
6583
6584    Args:
6585        table: Table name.
6586        db: Database name.
6587        catalog: Catalog name.
6588        quote: Whether to force quotes on the table's identifiers.
6589        alias: Table's alias.
6590
6591    Returns:
6592        The new Table instance.
6593    """
6594    return Table(
6595        this=to_identifier(table, quoted=quoted) if table else None,
6596        db=to_identifier(db, quoted=quoted) if db else None,
6597        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6598        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6599    )
6600
6601
6602def values(
6603    values: t.Iterable[t.Tuple[t.Any, ...]],
6604    alias: t.Optional[str] = None,
6605    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6606) -> Values:
6607    """Build VALUES statement.
6608
6609    Example:
6610        >>> values([(1, '2')]).sql()
6611        "VALUES (1, '2')"
6612
6613    Args:
6614        values: values statements that will be converted to SQL
6615        alias: optional alias
6616        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6617         If either are provided then an alias is also required.
6618
6619    Returns:
6620        Values: the Values expression object
6621    """
6622    if columns and not alias:
6623        raise ValueError("Alias is required when providing columns")
6624
6625    return Values(
6626        expressions=[convert(tup) for tup in values],
6627        alias=(
6628            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6629            if columns
6630            else (TableAlias(this=to_identifier(alias)) if alias else None)
6631        ),
6632    )
6633
6634
6635def var(name: t.Optional[ExpOrStr]) -> Var:
6636    """Build a SQL variable.
6637
6638    Example:
6639        >>> repr(var('x'))
6640        'Var(this=x)'
6641
6642        >>> repr(var(column('x', table='y')))
6643        'Var(this=x)'
6644
6645    Args:
6646        name: The name of the var or an expression who's name will become the var.
6647
6648    Returns:
6649        The new variable node.
6650    """
6651    if not name:
6652        raise ValueError("Cannot convert empty name into var.")
6653
6654    if isinstance(name, Expression):
6655        name = name.name
6656    return Var(this=name)
6657
6658
6659def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6660    """Build ALTER TABLE... RENAME... expression
6661
6662    Args:
6663        old_name: The old name of the table
6664        new_name: The new name of the table
6665
6666    Returns:
6667        Alter table expression
6668    """
6669    old_table = to_table(old_name)
6670    new_table = to_table(new_name)
6671    return AlterTable(
6672        this=old_table,
6673        actions=[
6674            RenameTable(this=new_table),
6675        ],
6676    )
6677
6678
6679def rename_column(
6680    table_name: str | Table,
6681    old_column_name: str | Column,
6682    new_column_name: str | Column,
6683    exists: t.Optional[bool] = None,
6684) -> AlterTable:
6685    """Build ALTER TABLE... RENAME COLUMN... expression
6686
6687    Args:
6688        table_name: Name of the table
6689        old_column: The old name of the column
6690        new_column: The new name of the column
6691        exists: Whether or not to add the `IF EXISTS` clause
6692
6693    Returns:
6694        Alter table expression
6695    """
6696    table = to_table(table_name)
6697    old_column = to_column(old_column_name)
6698    new_column = to_column(new_column_name)
6699    return AlterTable(
6700        this=table,
6701        actions=[
6702            RenameColumn(this=old_column, to=new_column, exists=exists),
6703        ],
6704    )
6705
6706
6707def convert(value: t.Any, copy: bool = False) -> Expression:
6708    """Convert a python value into an expression object.
6709
6710    Raises an error if a conversion is not possible.
6711
6712    Args:
6713        value: A python object.
6714        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6715
6716    Returns:
6717        Expression: the equivalent expression object.
6718    """
6719    if isinstance(value, Expression):
6720        return maybe_copy(value, copy)
6721    if isinstance(value, str):
6722        return Literal.string(value)
6723    if isinstance(value, bool):
6724        return Boolean(this=value)
6725    if value is None or (isinstance(value, float) and math.isnan(value)):
6726        return null()
6727    if isinstance(value, numbers.Number):
6728        return Literal.number(value)
6729    if isinstance(value, datetime.datetime):
6730        datetime_literal = Literal.string(
6731            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6732        )
6733        return TimeStrToTime(this=datetime_literal)
6734    if isinstance(value, datetime.date):
6735        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6736        return DateStrToDate(this=date_literal)
6737    if isinstance(value, tuple):
6738        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6739    if isinstance(value, list):
6740        return Array(expressions=[convert(v, copy=copy) for v in value])
6741    if isinstance(value, dict):
6742        return Map(
6743            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6744            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6745        )
6746    raise ValueError(f"Cannot convert {value}")
6747
6748
6749def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6750    """
6751    Replace children of an expression with the result of a lambda fun(child) -> exp.
6752    """
6753    for k, v in expression.args.items():
6754        is_list_arg = type(v) is list
6755
6756        child_nodes = v if is_list_arg else [v]
6757        new_child_nodes = []
6758
6759        for cn in child_nodes:
6760            if isinstance(cn, Expression):
6761                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6762                    new_child_nodes.append(child_node)
6763                    child_node.parent = expression
6764                    child_node.arg_key = k
6765            else:
6766                new_child_nodes.append(cn)
6767
6768        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
6769
6770
6771def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6772    """
6773    Return all table names referenced through columns in an expression.
6774
6775    Example:
6776        >>> import sqlglot
6777        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6778        ['a', 'c']
6779
6780    Args:
6781        expression: expression to find table names.
6782        exclude: a table name to exclude
6783
6784    Returns:
6785        A list of unique names.
6786    """
6787    return {
6788        table
6789        for table in (column.table for column in expression.find_all(Column))
6790        if table and table != exclude
6791    }
6792
6793
6794def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6795    """Get the full name of a table as a string.
6796
6797    Args:
6798        table: Table expression node or string.
6799        dialect: The dialect to generate the table name for.
6800        identify: Determines when an identifier should be quoted. Possible values are:
6801            False (default): Never quote, except in cases where it's mandatory by the dialect.
6802            True: Always quote.
6803
6804    Examples:
6805        >>> from sqlglot import exp, parse_one
6806        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6807        'a.b.c'
6808
6809    Returns:
6810        The table name.
6811    """
6812
6813    table = maybe_parse(table, into=Table, dialect=dialect)
6814
6815    if not table:
6816        raise ValueError(f"Cannot parse {table}")
6817
6818    return ".".join(
6819        (
6820            part.sql(dialect=dialect, identify=True, copy=False)
6821            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6822            else part.name
6823        )
6824        for part in table.parts
6825    )
6826
6827
6828def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6829    """Returns a case normalized table name without quotes.
6830
6831    Args:
6832        table: the table to normalize
6833        dialect: the dialect to use for normalization rules
6834        copy: whether or not to copy the expression.
6835
6836    Examples:
6837        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6838        'A-B.c'
6839    """
6840    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6841
6842    return ".".join(
6843        p.name
6844        for p in normalize_identifiers(
6845            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6846        ).parts
6847    )
6848
6849
6850def replace_tables(
6851    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6852) -> E:
6853    """Replace all tables in expression according to the mapping.
6854
6855    Args:
6856        expression: expression node to be transformed and replaced.
6857        mapping: mapping of table names.
6858        dialect: the dialect of the mapping table
6859        copy: whether or not to copy the expression.
6860
6861    Examples:
6862        >>> from sqlglot import exp, parse_one
6863        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6864        'SELECT * FROM c /* a.b */'
6865
6866    Returns:
6867        The mapped expression.
6868    """
6869
6870    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6871
6872    def _replace_tables(node: Expression) -> Expression:
6873        if isinstance(node, Table):
6874            original = normalize_table_name(node, dialect=dialect)
6875            new_name = mapping.get(original)
6876
6877            if new_name:
6878                table = to_table(
6879                    new_name,
6880                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6881                )
6882                table.add_comments([original])
6883                return table
6884        return node
6885
6886    return expression.transform(_replace_tables, copy=copy)
6887
6888
6889def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6890    """Replace placeholders in an expression.
6891
6892    Args:
6893        expression: expression node to be transformed and replaced.
6894        args: positional names that will substitute unnamed placeholders in the given order.
6895        kwargs: keyword arguments that will substitute named placeholders.
6896
6897    Examples:
6898        >>> from sqlglot import exp, parse_one
6899        >>> replace_placeholders(
6900        ...     parse_one("select * from :tbl where ? = ?"),
6901        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6902        ... ).sql()
6903        "SELECT * FROM foo WHERE str_col = 'b'"
6904
6905    Returns:
6906        The mapped expression.
6907    """
6908
6909    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6910        if isinstance(node, Placeholder):
6911            if node.name:
6912                new_name = kwargs.get(node.name)
6913                if new_name:
6914                    return convert(new_name)
6915            else:
6916                try:
6917                    return convert(next(args))
6918                except StopIteration:
6919                    pass
6920        return node
6921
6922    return expression.transform(_replace_placeholders, iter(args), **kwargs)
6923
6924
6925def expand(
6926    expression: Expression,
6927    sources: t.Dict[str, Subqueryable],
6928    dialect: DialectType = None,
6929    copy: bool = True,
6930) -> Expression:
6931    """Transforms an expression by expanding all referenced sources into subqueries.
6932
6933    Examples:
6934        >>> from sqlglot import parse_one
6935        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6936        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6937
6938        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6939        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6940
6941    Args:
6942        expression: The expression to expand.
6943        sources: A dictionary of name to Subqueryables.
6944        dialect: The dialect of the sources dict.
6945        copy: Whether or not to copy the expression during transformation. Defaults to True.
6946
6947    Returns:
6948        The transformed expression.
6949    """
6950    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6951
6952    def _expand(node: Expression):
6953        if isinstance(node, Table):
6954            name = normalize_table_name(node, dialect=dialect)
6955            source = sources.get(name)
6956            if source:
6957                subquery = source.subquery(node.alias or name)
6958                subquery.comments = [f"source: {name}"]
6959                return subquery.transform(_expand, copy=False)
6960        return node
6961
6962    return expression.transform(_expand, copy=copy)
6963
6964
6965def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6966    """
6967    Returns a Func expression.
6968
6969    Examples:
6970        >>> func("abs", 5).sql()
6971        'ABS(5)'
6972
6973        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6974        'CAST(5 AS DOUBLE)'
6975
6976    Args:
6977        name: the name of the function to build.
6978        args: the args used to instantiate the function of interest.
6979        copy: whether or not to copy the argument expressions.
6980        dialect: the source dialect.
6981        kwargs: the kwargs used to instantiate the function of interest.
6982
6983    Note:
6984        The arguments `args` and `kwargs` are mutually exclusive.
6985
6986    Returns:
6987        An instance of the function of interest, or an anonymous function, if `name` doesn't
6988        correspond to an existing `sqlglot.expressions.Func` class.
6989    """
6990    if args and kwargs:
6991        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6992
6993    from sqlglot.dialects.dialect import Dialect
6994
6995    dialect = Dialect.get_or_raise(dialect)
6996
6997    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6998    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6999
7000    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7001    if constructor:
7002        if converted:
7003            if "dialect" in constructor.__code__.co_varnames:
7004                function = constructor(converted, dialect=dialect)
7005            else:
7006                function = constructor(converted)
7007        elif constructor.__name__ == "from_arg_list":
7008            function = constructor.__self__(**kwargs)  # type: ignore
7009        else:
7010            constructor = FUNCTION_BY_NAME.get(name.upper())
7011            if constructor:
7012                function = constructor(**kwargs)
7013            else:
7014                raise ValueError(
7015                    f"Unable to convert '{name}' into a Func. Either manually construct "
7016                    "the Func expression of interest or parse the function call."
7017                )
7018    else:
7019        kwargs = kwargs or {"expressions": converted}
7020        function = Anonymous(this=name, **kwargs)
7021
7022    for error_message in function.error_messages(converted):
7023        raise ValueError(error_message)
7024
7025    return function
7026
7027
7028def case(
7029    expression: t.Optional[ExpOrStr] = None,
7030    **opts,
7031) -> Case:
7032    """
7033    Initialize a CASE statement.
7034
7035    Example:
7036        case().when("a = 1", "foo").else_("bar")
7037
7038    Args:
7039        expression: Optionally, the input expression (not all dialects support this)
7040        **opts: Extra keyword arguments for parsing `expression`
7041    """
7042    if expression is not None:
7043        this = maybe_parse(expression, **opts)
7044    else:
7045        this = None
7046    return Case(this=this, ifs=[])
7047
7048
7049def cast_unless(
7050    expression: ExpOrStr,
7051    to: DATA_TYPE,
7052    *types: DATA_TYPE,
7053    **opts: t.Any,
7054) -> Expression | Cast:
7055    """
7056    Cast an expression to a data type unless it is a specified type.
7057
7058    Args:
7059        expression: The expression to cast.
7060        to: The data type to cast to.
7061        **types: The types to exclude from casting.
7062        **opts: Extra keyword arguments for parsing `expression`
7063    """
7064    expr = maybe_parse(expression, **opts)
7065    if expr.is_type(*types):
7066        return expr
7067    return cast(expr, to, **opts)
7068
7069
7070def true() -> Boolean:
7071    """
7072    Returns a true Boolean expression.
7073    """
7074    return Boolean(this=True)
7075
7076
7077def false() -> Boolean:
7078    """
7079    Returns a false Boolean expression.
7080    """
7081    return Boolean(this=False)
7082
7083
7084def null() -> Null:
7085    """
7086    Returns a Null expression.
7087    """
7088    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}
arg_types = {'this': False, 'expression': True, 'offset': 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}
arg_types = {'this': False, 'expression': True}
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.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME64: 'DATETIME64'>}
@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 Func(Condition):
4296class Func(Condition):
4297    """
4298    The base class for all function expressions.
4299
4300    Attributes:
4301        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4302            treated as a variable length argument and the argument's value will be stored as a list.
4303        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4304            for this function expression. These values are used to map this node to a name during parsing
4305            as well as to provide the function's name during SQL string generation. By default the SQL
4306            name is set to the expression's class name transformed to snake case.
4307    """
4308
4309    is_var_len_args = False
4310
4311    @classmethod
4312    def from_arg_list(cls, args):
4313        if cls.is_var_len_args:
4314            all_arg_keys = list(cls.arg_types)
4315            # If this function supports variable length argument treat the last argument as such.
4316            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4317            num_non_var = len(non_var_len_arg_keys)
4318
4319            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4320            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4321        else:
4322            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4323
4324        return cls(**args_dict)
4325
4326    @classmethod
4327    def sql_names(cls):
4328        if cls is Func:
4329            raise NotImplementedError(
4330                "SQL name is only supported by concrete function implementations"
4331            )
4332        if "_sql_names" not in cls.__dict__:
4333            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4334        return cls._sql_names
4335
4336    @classmethod
4337    def sql_name(cls):
4338        return cls.sql_names()[0]
4339
4340    @classmethod
4341    def default_parser_mappings(cls):
4342        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):
4311    @classmethod
4312    def from_arg_list(cls, args):
4313        if cls.is_var_len_args:
4314            all_arg_keys = list(cls.arg_types)
4315            # If this function supports variable length argument treat the last argument as such.
4316            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4317            num_non_var = len(non_var_len_arg_keys)
4318
4319            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4320            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4321        else:
4322            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4323
4324        return cls(**args_dict)
@classmethod
def sql_names(cls):
4326    @classmethod
4327    def sql_names(cls):
4328        if cls is Func:
4329            raise NotImplementedError(
4330                "SQL name is only supported by concrete function implementations"
4331            )
4332        if "_sql_names" not in cls.__dict__:
4333            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4334        return cls._sql_names
@classmethod
def sql_name(cls):
4336    @classmethod
4337    def sql_name(cls):
4338        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4340    @classmethod
4341    def default_parser_mappings(cls):
4342        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4345class AggFunc(Func):
4346    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4349class ParameterizedAgg(AggFunc):
4350    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4353class Abs(Func):
4354    pass
key = 'abs'
class ArgMax(AggFunc):
4357class ArgMax(AggFunc):
4358    arg_types = {"this": True, "expression": True, "count": False}
4359    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4362class ArgMin(AggFunc):
4363    arg_types = {"this": True, "expression": True, "count": False}
4364    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4367class ApproxTopK(AggFunc):
4368    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4371class Flatten(Func):
4372    pass
key = 'flatten'
class Transform(Func):
4376class Transform(Func):
4377    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4380class Anonymous(Func):
4381    arg_types = {"this": True, "expressions": False}
4382    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4385class AnonymousAggFunc(AggFunc):
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 = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4391class CombinedAggFunc(AnonymousAggFunc):
4392    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4395class CombinedParameterizedAgg(ParameterizedAgg):
4396    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):
4401class Hll(AggFunc):
4402    arg_types = {"this": True, "expressions": False}
4403    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4406class ApproxDistinct(AggFunc):
4407    arg_types = {"this": True, "accuracy": False}
4408    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4411class Array(Func):
4412    arg_types = {"expressions": False}
4413    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4417class ToArray(Func):
4418    pass
key = 'toarray'
class ToChar(Func):
4423class ToChar(Func):
4424    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4427class GenerateSeries(Func):
4428    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4431class ArrayAgg(AggFunc):
4432    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4435class ArrayUniqueAgg(AggFunc):
4436    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4439class ArrayAll(Func):
4440    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4443class ArrayAny(Func):
4444    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4447class ArrayConcat(Func):
4448    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4449    arg_types = {"this": True, "expressions": False}
4450    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4453class ArrayContains(Binary, Func):
4454    pass
key = 'arraycontains'
class ArrayContained(Binary):
4457class ArrayContained(Binary):
4458    pass
key = 'arraycontained'
class ArrayFilter(Func):
4461class ArrayFilter(Func):
4462    arg_types = {"this": True, "expression": True}
4463    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4466class ArrayJoin(Func):
4467    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4470class ArrayOverlaps(Binary, Func):
4471    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4474class ArraySize(Func):
4475    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4478class ArraySort(Func):
4479    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4482class ArraySum(Func):
4483    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4486class ArrayUnionAgg(AggFunc):
4487    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4490class Avg(AggFunc):
4491    pass
key = 'avg'
class AnyValue(AggFunc):
4494class AnyValue(AggFunc):
4495    arg_types = {"this": True, "having": False, "max": False}
arg_types = {'this': True, 'having': False, 'max': False}
key = 'anyvalue'
class Lag(AggFunc):
4498class Lag(AggFunc):
4499    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4502class Lead(AggFunc):
4503    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4508class First(AggFunc):
4509    pass
key = 'first'
class Last(AggFunc):
4512class Last(AggFunc):
4513    pass
key = 'last'
class FirstValue(AggFunc):
4516class FirstValue(AggFunc):
4517    pass
key = 'firstvalue'
class LastValue(AggFunc):
4520class LastValue(AggFunc):
4521    pass
key = 'lastvalue'
class NthValue(AggFunc):
4524class NthValue(AggFunc):
4525    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4528class Case(Func):
4529    arg_types = {"this": False, "ifs": True, "default": False}
4530
4531    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4532        instance = maybe_copy(self, copy)
4533        instance.append(
4534            "ifs",
4535            If(
4536                this=maybe_parse(condition, copy=copy, **opts),
4537                true=maybe_parse(then, copy=copy, **opts),
4538            ),
4539        )
4540        return instance
4541
4542    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4543        instance = maybe_copy(self, copy)
4544        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4545        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:
4531    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4532        instance = maybe_copy(self, copy)
4533        instance.append(
4534            "ifs",
4535            If(
4536                this=maybe_parse(condition, copy=copy, **opts),
4537                true=maybe_parse(then, copy=copy, **opts),
4538            ),
4539        )
4540        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4542    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4543        instance = maybe_copy(self, copy)
4544        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4545        return instance
key = 'case'
class Cast(Func):
4548class Cast(Func):
4549    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4550
4551    @property
4552    def name(self) -> str:
4553        return self.this.name
4554
4555    @property
4556    def to(self) -> DataType:
4557        return self.args["to"]
4558
4559    @property
4560    def output_name(self) -> str:
4561        return self.name
4562
4563    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4564        """
4565        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4566        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4567        array<int> != array<float>.
4568
4569        Args:
4570            dtypes: the data types to compare this Cast's DataType to.
4571
4572        Returns:
4573            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4574        """
4575        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4551    @property
4552    def name(self) -> str:
4553        return self.this.name
to: DataType
4555    @property
4556    def to(self) -> DataType:
4557        return self.args["to"]
output_name: str
4559    @property
4560    def output_name(self) -> str:
4561        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:
4563    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4564        """
4565        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4566        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4567        array<int> != array<float>.
4568
4569        Args:
4570            dtypes: the data types to compare this Cast's DataType to.
4571
4572        Returns:
4573            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4574        """
4575        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):
4578class TryCast(Cast):
4579    pass
key = 'trycast'
class CastToStrType(Func):
4582class CastToStrType(Func):
4583    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4586class Collate(Binary, Func):
4587    pass
key = 'collate'
class Ceil(Func):
4590class Ceil(Func):
4591    arg_types = {"this": True, "decimals": False}
4592    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4595class Coalesce(Func):
4596    arg_types = {"this": True, "expressions": False}
4597    is_var_len_args = True
4598    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4601class Chr(Func):
4602    arg_types = {"this": True, "charset": False, "expressions": False}
4603    is_var_len_args = True
4604    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4607class Concat(Func):
4608    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4609    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4612class ConcatWs(Concat):
4613    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4616class Count(AggFunc):
4617    arg_types = {"this": False, "expressions": False}
4618    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4621class CountIf(AggFunc):
4622    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4625class CurrentDate(Func):
4626    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4629class CurrentDatetime(Func):
4630    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4633class CurrentTime(Func):
4634    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4637class CurrentTimestamp(Func):
4638    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4641class CurrentUser(Func):
4642    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4645class DateAdd(Func, IntervalOp):
4646    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4649class DateSub(Func, IntervalOp):
4650    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4653class DateDiff(Func, TimeUnit):
4654    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4655    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4658class DateTrunc(Func):
4659    arg_types = {"unit": True, "this": True, "zone": False}
4660
4661    def __init__(self, **args):
4662        unit = args.get("unit")
4663        if isinstance(unit, TimeUnit.VAR_LIKE):
4664            args["unit"] = Literal.string(
4665                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4666            )
4667        elif isinstance(unit, Week):
4668            unit.set("this", Literal.string(unit.this.name.upper()))
4669
4670        super().__init__(**args)
4671
4672    @property
4673    def unit(self) -> Expression:
4674        return self.args["unit"]
DateTrunc(**args)
4661    def __init__(self, **args):
4662        unit = args.get("unit")
4663        if isinstance(unit, TimeUnit.VAR_LIKE):
4664            args["unit"] = Literal.string(
4665                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4666            )
4667        elif isinstance(unit, Week):
4668            unit.set("this", Literal.string(unit.this.name.upper()))
4669
4670        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4672    @property
4673    def unit(self) -> Expression:
4674        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4677class DatetimeAdd(Func, IntervalOp):
4678    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4681class DatetimeSub(Func, IntervalOp):
4682    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4685class DatetimeDiff(Func, TimeUnit):
4686    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4689class DatetimeTrunc(Func, TimeUnit):
4690    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4693class DayOfWeek(Func):
4694    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4697class DayOfMonth(Func):
4698    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4701class DayOfYear(Func):
4702    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4705class ToDays(Func):
4706    pass
key = 'todays'
class WeekOfYear(Func):
4709class WeekOfYear(Func):
4710    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4713class MonthsBetween(Func):
4714    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4717class LastDay(Func, TimeUnit):
4718    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4719    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4722class Extract(Func):
4723    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4726class Timestamp(Func):
4727    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4730class TimestampAdd(Func, TimeUnit):
4731    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4734class TimestampSub(Func, TimeUnit):
4735    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4738class TimestampDiff(Func, TimeUnit):
4739    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4740    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4743class TimestampTrunc(Func, TimeUnit):
4744    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4747class TimeAdd(Func, TimeUnit):
4748    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4751class TimeSub(Func, TimeUnit):
4752    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4755class TimeDiff(Func, TimeUnit):
4756    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4759class TimeTrunc(Func, TimeUnit):
4760    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4763class DateFromParts(Func):
4764    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4765    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4768class TimeFromParts(Func):
4769    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4770    arg_types = {
4771        "hour": True,
4772        "min": True,
4773        "sec": True,
4774        "nano": False,
4775        "fractions": False,
4776        "precision": False,
4777    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4780class DateStrToDate(Func):
4781    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4784class DateToDateStr(Func):
4785    pass
key = 'datetodatestr'
class DateToDi(Func):
4788class DateToDi(Func):
4789    pass
key = 'datetodi'
class Date(Func):
4793class Date(Func):
4794    arg_types = {"this": False, "zone": False, "expressions": False}
4795    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4798class Day(Func):
4799    pass
key = 'day'
class Decode(Func):
4802class Decode(Func):
4803    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4806class DiToDate(Func):
4807    pass
key = 'ditodate'
class Encode(Func):
4810class Encode(Func):
4811    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4814class Exp(Func):
4815    pass
key = 'exp'
class Explode(Func):
4819class Explode(Func):
4820    arg_types = {"this": True, "expressions": False}
4821    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4824class ExplodeOuter(Explode):
4825    pass
key = 'explodeouter'
class Posexplode(Explode):
4828class Posexplode(Explode):
4829    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4832class PosexplodeOuter(Posexplode):
4833    pass
key = 'posexplodeouter'
class Floor(Func):
4836class Floor(Func):
4837    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4840class FromBase64(Func):
4841    pass
key = 'frombase64'
class ToBase64(Func):
4844class ToBase64(Func):
4845    pass
key = 'tobase64'
class Greatest(Func):
4848class Greatest(Func):
4849    arg_types = {"this": True, "expressions": False}
4850    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4853class GroupConcat(AggFunc):
4854    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4857class Hex(Func):
4858    pass
key = 'hex'
class Xor(Connector, Func):
4861class Xor(Connector, Func):
4862    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4865class If(Func):
4866    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4869class Nullif(Func):
4870    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4873class Initcap(Func):
4874    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4877class IsNan(Func):
4878    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4881class IsInf(Func):
4882    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
4885class JSONPath(Expression):
4886    arg_types = {"expressions": True}
4887
4888    @property
4889    def output_name(self) -> str:
4890        last_segment = self.expressions[-1].this
4891        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
4888    @property
4889    def output_name(self) -> str:
4890        last_segment = self.expressions[-1].this
4891        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):
4894class JSONPathPart(Expression):
4895    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
4898class JSONPathFilter(JSONPathPart):
4899    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
4902class JSONPathKey(JSONPathPart):
4903    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
4906class JSONPathRecursive(JSONPathPart):
4907    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
4910class JSONPathRoot(JSONPathPart):
4911    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
4914class JSONPathScript(JSONPathPart):
4915    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
4918class JSONPathSlice(JSONPathPart):
4919    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
4922class JSONPathSelector(JSONPathPart):
4923    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
4926class JSONPathSubscript(JSONPathPart):
4927    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
4930class JSONPathUnion(JSONPathPart):
4931    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
4934class JSONPathWildcard(JSONPathPart):
4935    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
4938class FormatJson(Expression):
4939    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4942class JSONKeyValue(Expression):
4943    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4946class JSONObject(Func):
4947    arg_types = {
4948        "expressions": False,
4949        "null_handling": False,
4950        "unique_keys": False,
4951        "return_type": False,
4952        "encoding": False,
4953    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
4956class JSONObjectAgg(AggFunc):
4957    arg_types = {
4958        "expressions": False,
4959        "null_handling": False,
4960        "unique_keys": False,
4961        "return_type": False,
4962        "encoding": False,
4963    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
4967class JSONArray(Func):
4968    arg_types = {
4969        "expressions": True,
4970        "null_handling": False,
4971        "return_type": False,
4972        "strict": False,
4973    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4977class JSONArrayAgg(Func):
4978    arg_types = {
4979        "this": True,
4980        "order": False,
4981        "null_handling": False,
4982        "return_type": False,
4983        "strict": False,
4984    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4989class JSONColumnDef(Expression):
4990    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):
4993class JSONSchema(Expression):
4994    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4998class JSONTable(Func):
4999    arg_types = {
5000        "this": True,
5001        "schema": True,
5002        "path": False,
5003        "error_handling": False,
5004        "empty_handling": False,
5005    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5008class OpenJSONColumnDef(Expression):
5009    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):
5012class OpenJSON(Func):
5013    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5016class JSONBContains(Binary):
5017    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5020class JSONExtract(Binary, Func):
5021    # MySQL and SQLite support a variant of JSON_EXTRACT where you can have multiple JSON
5022    # paths and you get back a list of values. These paths will be stored in `expressions`
5023    arg_types = {"this": True, "expression": True, "expressions": False}
5024    _sql_names = ["JSON_EXTRACT"]
5025
5026    @property
5027    def output_name(self) -> str:
5028        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'expressions': False}
output_name: str
5026    @property
5027    def output_name(self) -> str:
5028        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):
5031class JSONExtractScalar(Binary, Func):
5032    arg_types = {"this": True, "expression": True, "null_if_invalid": False}
5033    _sql_names = ["JSON_EXTRACT_SCALAR"]
5034
5035    @property
5036    def output_name(self) -> str:
5037        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'null_if_invalid': False}
output_name: str
5035    @property
5036    def output_name(self) -> str:
5037        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):
5040class JSONBExtract(Binary, Func):
5041    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5044class JSONBExtractScalar(Binary, Func):
5045    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5048class JSONFormat(Func):
5049    arg_types = {"this": False, "options": False}
5050    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5054class JSONArrayContains(Binary, Predicate, Func):
5055    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5058class ParseJSON(Func):
5059    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5060    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5061    arg_types = {"this": True, "expressions": False}
5062    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5065class Least(Func):
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 = 'least'
class Left(Func):
5070class Left(Func):
5071    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5078class Length(Func):
5079    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5082class Levenshtein(Func):
5083    arg_types = {
5084        "this": True,
5085        "expression": False,
5086        "ins_cost": False,
5087        "del_cost": False,
5088        "sub_cost": False,
5089    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5092class Ln(Func):
5093    pass
key = 'ln'
class Log(Func):
5096class Log(Func):
5097    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5100class Log2(Func):
5101    pass
key = 'log2'
class Log10(Func):
5104class Log10(Func):
5105    pass
key = 'log10'
class LogicalOr(AggFunc):
5108class LogicalOr(AggFunc):
5109    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5112class LogicalAnd(AggFunc):
5113    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5116class Lower(Func):
5117    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5120class Map(Func):
5121    arg_types = {"keys": False, "values": False}
5122
5123    @property
5124    def keys(self) -> t.List[Expression]:
5125        keys = self.args.get("keys")
5126        return keys.expressions if keys else []
5127
5128    @property
5129    def values(self) -> t.List[Expression]:
5130        values = self.args.get("values")
5131        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5123    @property
5124    def keys(self) -> t.List[Expression]:
5125        keys = self.args.get("keys")
5126        return keys.expressions if keys else []
values: List[Expression]
5128    @property
5129    def values(self) -> t.List[Expression]:
5130        values = self.args.get("values")
5131        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5134class MapFromEntries(Func):
5135    pass
key = 'mapfromentries'
class StarMap(Func):
5138class StarMap(Func):
5139    pass
key = 'starmap'
class VarMap(Func):
5142class VarMap(Func):
5143    arg_types = {"keys": True, "values": True}
5144    is_var_len_args = True
5145
5146    @property
5147    def keys(self) -> t.List[Expression]:
5148        return self.args["keys"].expressions
5149
5150    @property
5151    def values(self) -> t.List[Expression]:
5152        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5146    @property
5147    def keys(self) -> t.List[Expression]:
5148        return self.args["keys"].expressions
values: List[Expression]
5150    @property
5151    def values(self) -> t.List[Expression]:
5152        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5156class MatchAgainst(Func):
5157    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5160class Max(AggFunc):
5161    arg_types = {"this": True, "expressions": False}
5162    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5165class MD5(Func):
5166    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5170class MD5Digest(Func):
5171    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5174class Min(AggFunc):
5175    arg_types = {"this": True, "expressions": False}
5176    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5179class Month(Func):
5180    pass
key = 'month'
class Nvl2(Func):
5183class Nvl2(Func):
5184    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5188class Predict(Func):
5189    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5192class Pow(Binary, Func):
5193    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5196class PercentileCont(AggFunc):
5197    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5200class PercentileDisc(AggFunc):
5201    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5204class Quantile(AggFunc):
5205    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5208class ApproxQuantile(Quantile):
5209    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):
5212class Rand(Func):
5213    _sql_names = ["RAND", "RANDOM"]
5214    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5217class Randn(Func):
5218    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5221class RangeN(Func):
5222    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5225class ReadCSV(Func):
5226    _sql_names = ["READ_CSV"]
5227    is_var_len_args = True
5228    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5231class Reduce(Func):
5232    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):
5235class RegexpExtract(Func):
5236    arg_types = {
5237        "this": True,
5238        "expression": True,
5239        "position": False,
5240        "occurrence": False,
5241        "parameters": False,
5242        "group": False,
5243    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5246class RegexpReplace(Func):
5247    arg_types = {
5248        "this": True,
5249        "expression": True,
5250        "replacement": False,
5251        "position": False,
5252        "occurrence": False,
5253        "parameters": False,
5254        "modifiers": False,
5255    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5258class RegexpLike(Binary, Func):
5259    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5262class RegexpILike(Binary, Func):
5263    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5268class RegexpSplit(Func):
5269    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5272class Repeat(Func):
5273    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5278class Round(Func):
5279    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5282class RowNumber(Func):
5283    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5286class SafeDivide(Func):
5287    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5290class SHA(Func):
5291    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5294class SHA2(Func):
5295    _sql_names = ["SHA2"]
5296    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5299class SortArray(Func):
5300    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5303class Split(Func):
5304    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5309class Substring(Func):
5310    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5313class StandardHash(Func):
5314    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5317class StartsWith(Func):
5318    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5319    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5322class StrPosition(Func):
5323    arg_types = {
5324        "this": True,
5325        "substr": True,
5326        "position": False,
5327        "instance": False,
5328    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5331class StrToDate(Func):
5332    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5335class StrToTime(Func):
5336    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5341class StrToUnix(Func):
5342    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5347class StrToMap(Func):
5348    arg_types = {
5349        "this": True,
5350        "pair_delim": False,
5351        "key_value_delim": False,
5352        "duplicate_resolution_callback": False,
5353    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5356class NumberToStr(Func):
5357    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5360class FromBase(Func):
5361    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5364class Struct(Func):
5365    arg_types = {"expressions": False}
5366    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5369class StructExtract(Func):
5370    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5375class Stuff(Func):
5376    _sql_names = ["STUFF", "INSERT"]
5377    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):
5380class Sum(AggFunc):
5381    pass
key = 'sum'
class Sqrt(Func):
5384class Sqrt(Func):
5385    pass
key = 'sqrt'
class Stddev(AggFunc):
5388class Stddev(AggFunc):
5389    pass
key = 'stddev'
class StddevPop(AggFunc):
5392class StddevPop(AggFunc):
5393    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5396class StddevSamp(AggFunc):
5397    pass
key = 'stddevsamp'
class TimeToStr(Func):
5400class TimeToStr(Func):
5401    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5404class TimeToTimeStr(Func):
5405    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5408class TimeToUnix(Func):
5409    pass
key = 'timetounix'
class TimeStrToDate(Func):
5412class TimeStrToDate(Func):
5413    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5416class TimeStrToTime(Func):
5417    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5420class TimeStrToUnix(Func):
5421    pass
key = 'timestrtounix'
class Trim(Func):
5424class Trim(Func):
5425    arg_types = {
5426        "this": True,
5427        "expression": False,
5428        "position": False,
5429        "collation": False,
5430    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5433class TsOrDsAdd(Func, TimeUnit):
5434    # return_type is used to correctly cast the arguments of this expression when transpiling it
5435    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5436
5437    @property
5438    def return_type(self) -> DataType:
5439        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
5437    @property
5438    def return_type(self) -> DataType:
5439        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5442class TsOrDsDiff(Func, TimeUnit):
5443    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5446class TsOrDsToDateStr(Func):
5447    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5450class TsOrDsToDate(Func):
5451    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5454class TsOrDsToTime(Func):
5455    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5458class TsOrDiToDi(Func):
5459    pass
key = 'tsorditodi'
class Unhex(Func):
5462class Unhex(Func):
5463    pass
key = 'unhex'
class UnixDate(Func):
5467class UnixDate(Func):
5468    pass
key = 'unixdate'
class UnixToStr(Func):
5471class UnixToStr(Func):
5472    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5477class UnixToTime(Func):
5478    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5479
5480    SECONDS = Literal.number(0)
5481    DECIS = Literal.number(1)
5482    CENTIS = Literal.number(2)
5483    MILLIS = Literal.number(3)
5484    DECIMILLIS = Literal.number(4)
5485    CENTIMILLIS = Literal.number(5)
5486    MICROS = Literal.number(6)
5487    DECIMICROS = Literal.number(7)
5488    CENTIMICROS = Literal.number(8)
5489    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):
5492class UnixToTimeStr(Func):
5493    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5496class TimestampFromParts(Func):
5497    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5498    arg_types = {
5499        "year": True,
5500        "month": True,
5501        "day": True,
5502        "hour": True,
5503        "min": True,
5504        "sec": True,
5505        "nano": False,
5506        "zone": False,
5507        "milli": False,
5508    }
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):
5511class Upper(Func):
5512    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5515class Variance(AggFunc):
5516    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5519class VariancePop(AggFunc):
5520    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5523class Week(Func):
5524    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5527class XMLTable(Func):
5528    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):
5531class Year(Func):
5532    pass
key = 'year'
class Use(Expression):
5535class Use(Expression):
5536    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5539class Merge(Expression):
5540    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):
5543class When(Func):
5544    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):
5549class NextValueFor(Func):
5550    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:
5590def maybe_parse(
5591    sql_or_expression: ExpOrStr,
5592    *,
5593    into: t.Optional[IntoType] = None,
5594    dialect: DialectType = None,
5595    prefix: t.Optional[str] = None,
5596    copy: bool = False,
5597    **opts,
5598) -> Expression:
5599    """Gracefully handle a possible string or expression.
5600
5601    Example:
5602        >>> maybe_parse("1")
5603        Literal(this=1, is_string=False)
5604        >>> maybe_parse(to_identifier("x"))
5605        Identifier(this=x, quoted=False)
5606
5607    Args:
5608        sql_or_expression: the SQL code string or an expression
5609        into: the SQLGlot Expression to parse into
5610        dialect: the dialect used to parse the input expressions (in the case that an
5611            input expression is a SQL string).
5612        prefix: a string to prefix the sql with before it gets parsed
5613            (automatically includes a space)
5614        copy: whether or not to copy the expression.
5615        **opts: other options to use to parse the input expressions (again, in the case
5616            that an input expression is a SQL string).
5617
5618    Returns:
5619        Expression: the parsed or given expression.
5620    """
5621    if isinstance(sql_or_expression, Expression):
5622        if copy:
5623            return sql_or_expression.copy()
5624        return sql_or_expression
5625
5626    if sql_or_expression is None:
5627        raise ParseError("SQL cannot be None")
5628
5629    import sqlglot
5630
5631    sql = str(sql_or_expression)
5632    if prefix:
5633        sql = f"{prefix} {sql}"
5634
5635    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):
5648def maybe_copy(instance, copy=True):
5649    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:
5863def union(
5864    left: ExpOrStr,
5865    right: ExpOrStr,
5866    distinct: bool = True,
5867    dialect: DialectType = None,
5868    copy: bool = True,
5869    **opts,
5870) -> Union:
5871    """
5872    Initializes a syntax tree from one UNION expression.
5873
5874    Example:
5875        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5876        'SELECT * FROM foo UNION SELECT * FROM bla'
5877
5878    Args:
5879        left: the SQL code string corresponding to the left-hand side.
5880            If an `Expression` instance is passed, it will be used as-is.
5881        right: the SQL code string corresponding to the right-hand side.
5882            If an `Expression` instance is passed, it will be used as-is.
5883        distinct: set the DISTINCT flag if and only if this is true.
5884        dialect: the dialect used to parse the input expression.
5885        copy: whether or not to copy the expression.
5886        opts: other options to use to parse the input expressions.
5887
5888    Returns:
5889        The new Union instance.
5890    """
5891    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5892    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5893
5894    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:
5897def intersect(
5898    left: ExpOrStr,
5899    right: ExpOrStr,
5900    distinct: bool = True,
5901    dialect: DialectType = None,
5902    copy: bool = True,
5903    **opts,
5904) -> Intersect:
5905    """
5906    Initializes a syntax tree from one INTERSECT expression.
5907
5908    Example:
5909        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5910        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5911
5912    Args:
5913        left: the SQL code string corresponding to the left-hand side.
5914            If an `Expression` instance is passed, it will be used as-is.
5915        right: the SQL code string corresponding to the right-hand side.
5916            If an `Expression` instance is passed, it will be used as-is.
5917        distinct: set the DISTINCT flag if and only if this is true.
5918        dialect: the dialect used to parse the input expression.
5919        copy: whether or not to copy the expression.
5920        opts: other options to use to parse the input expressions.
5921
5922    Returns:
5923        The new Intersect instance.
5924    """
5925    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5926    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5927
5928    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:
5931def except_(
5932    left: ExpOrStr,
5933    right: ExpOrStr,
5934    distinct: bool = True,
5935    dialect: DialectType = None,
5936    copy: bool = True,
5937    **opts,
5938) -> Except:
5939    """
5940    Initializes a syntax tree from one EXCEPT expression.
5941
5942    Example:
5943        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5944        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5945
5946    Args:
5947        left: the SQL code string corresponding to the left-hand side.
5948            If an `Expression` instance is passed, it will be used as-is.
5949        right: the SQL code string corresponding to the right-hand side.
5950            If an `Expression` instance is passed, it will be used as-is.
5951        distinct: set the DISTINCT flag if and only if this is true.
5952        dialect: the dialect used to parse the input expression.
5953        copy: whether or not to copy the expression.
5954        opts: other options to use to parse the input expressions.
5955
5956    Returns:
5957        The new Except instance.
5958    """
5959    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5960    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5961
5962    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:
5965def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5966    """
5967    Initializes a syntax tree from one or multiple SELECT expressions.
5968
5969    Example:
5970        >>> select("col1", "col2").from_("tbl").sql()
5971        'SELECT col1, col2 FROM tbl'
5972
5973    Args:
5974        *expressions: the SQL code string to parse as the expressions of a
5975            SELECT statement. If an Expression instance is passed, this is used as-is.
5976        dialect: the dialect used to parse the input expressions (in the case that an
5977            input expression is a SQL string).
5978        **opts: other options to use to parse the input expressions (again, in the case
5979            that an input expression is a SQL string).
5980
5981    Returns:
5982        Select: the syntax tree for the SELECT statement.
5983    """
5984    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:
5987def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5988    """
5989    Initializes a syntax tree from a FROM expression.
5990
5991    Example:
5992        >>> from_("tbl").select("col1", "col2").sql()
5993        'SELECT col1, col2 FROM tbl'
5994
5995    Args:
5996        *expression: the SQL code string to parse as the FROM expressions of a
5997            SELECT statement. If an Expression instance is passed, this is used as-is.
5998        dialect: the dialect used to parse the input expression (in the case that the
5999            input expression is a SQL string).
6000        **opts: other options to use to parse the input expressions (again, in the case
6001            that the input expression is a SQL string).
6002
6003    Returns:
6004        Select: the syntax tree for the SELECT statement.
6005    """
6006    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:
6009def update(
6010    table: str | Table,
6011    properties: dict,
6012    where: t.Optional[ExpOrStr] = None,
6013    from_: t.Optional[ExpOrStr] = None,
6014    dialect: DialectType = None,
6015    **opts,
6016) -> Update:
6017    """
6018    Creates an update statement.
6019
6020    Example:
6021        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6022        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6023
6024    Args:
6025        *properties: dictionary of properties to set which are
6026            auto converted to sql objects eg None -> NULL
6027        where: sql conditional parsed into a WHERE statement
6028        from_: sql statement parsed into a FROM statement
6029        dialect: the dialect used to parse the input expressions.
6030        **opts: other options to use to parse the input expressions.
6031
6032    Returns:
6033        Update: the syntax tree for the UPDATE statement.
6034    """
6035    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6036    update_expr.set(
6037        "expressions",
6038        [
6039            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6040            for k, v in properties.items()
6041        ],
6042    )
6043    if from_:
6044        update_expr.set(
6045            "from",
6046            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6047        )
6048    if isinstance(where, Condition):
6049        where = Where(this=where)
6050    if where:
6051        update_expr.set(
6052            "where",
6053            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6054        )
6055    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:
6058def delete(
6059    table: ExpOrStr,
6060    where: t.Optional[ExpOrStr] = None,
6061    returning: t.Optional[ExpOrStr] = None,
6062    dialect: DialectType = None,
6063    **opts,
6064) -> Delete:
6065    """
6066    Builds a delete statement.
6067
6068    Example:
6069        >>> delete("my_table", where="id > 1").sql()
6070        'DELETE FROM my_table WHERE id > 1'
6071
6072    Args:
6073        where: sql conditional parsed into a WHERE statement
6074        returning: sql conditional parsed into a RETURNING statement
6075        dialect: the dialect used to parse the input expressions.
6076        **opts: other options to use to parse the input expressions.
6077
6078    Returns:
6079        Delete: the syntax tree for the DELETE statement.
6080    """
6081    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6082    if where:
6083        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6084    if returning:
6085        delete_expr = t.cast(
6086            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6087        )
6088    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:
6091def insert(
6092    expression: ExpOrStr,
6093    into: ExpOrStr,
6094    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6095    overwrite: t.Optional[bool] = None,
6096    returning: t.Optional[ExpOrStr] = None,
6097    dialect: DialectType = None,
6098    copy: bool = True,
6099    **opts,
6100) -> Insert:
6101    """
6102    Builds an INSERT statement.
6103
6104    Example:
6105        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6106        'INSERT INTO tbl VALUES (1, 2, 3)'
6107
6108    Args:
6109        expression: the sql string or expression of the INSERT statement
6110        into: the tbl to insert data to.
6111        columns: optionally the table's column names.
6112        overwrite: whether to INSERT OVERWRITE or not.
6113        returning: sql conditional parsed into a RETURNING statement
6114        dialect: the dialect used to parse the input expressions.
6115        copy: whether or not to copy the expression.
6116        **opts: other options to use to parse the input expressions.
6117
6118    Returns:
6119        Insert: the syntax tree for the INSERT statement.
6120    """
6121    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6122    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6123
6124    if columns:
6125        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6126
6127    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6128
6129    if returning:
6130        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6131
6132    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:
6135def condition(
6136    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6137) -> Condition:
6138    """
6139    Initialize a logical condition expression.
6140
6141    Example:
6142        >>> condition("x=1").sql()
6143        'x = 1'
6144
6145        This is helpful for composing larger logical syntax trees:
6146        >>> where = condition("x=1")
6147        >>> where = where.and_("y=1")
6148        >>> Select().from_("tbl").select("*").where(where).sql()
6149        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6150
6151    Args:
6152        *expression: the SQL code string to parse.
6153            If an Expression instance is passed, this is used as-is.
6154        dialect: the dialect used to parse the input expression (in the case that the
6155            input expression is a SQL string).
6156        copy: Whether or not to copy `expression` (only applies to expressions).
6157        **opts: other options to use to parse the input expressions (again, in the case
6158            that the input expression is a SQL string).
6159
6160    Returns:
6161        The new Condition instance
6162    """
6163    return maybe_parse(
6164        expression,
6165        into=Condition,
6166        dialect=dialect,
6167        copy=copy,
6168        **opts,
6169    )

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

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

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

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

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

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

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

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

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

Returns a true Boolean expression.

def false() -> Boolean:
7078def false() -> Boolean:
7079    """
7080    Returns a false Boolean expression.
7081    """
7082    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7085def null() -> Null:
7086    """
7087    Returns a Null expression.
7088    """
7089    return Null()

Returns a Null expression.