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

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

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

Converts the column into a dot expression.

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

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

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):
1571class Drop(Expression):
1572    arg_types = {
1573        "this": False,
1574        "kind": False,
1575        "exists": False,
1576        "temporary": False,
1577        "materialized": False,
1578        "cascade": False,
1579        "constraints": False,
1580        "purge": False,
1581    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1584class Filter(Expression):
1585    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1588class Check(Expression):
1589    pass
key = 'check'
class Connect(Expression):
1593class Connect(Expression):
1594    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1597class Prior(Expression):
1598    pass
key = 'prior'
class Directory(Expression):
1601class Directory(Expression):
1602    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1603    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1606class ForeignKey(Expression):
1607    arg_types = {
1608        "expressions": True,
1609        "reference": False,
1610        "delete": False,
1611        "update": False,
1612    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1615class ColumnPrefix(Expression):
1616    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1619class PrimaryKey(Expression):
1620    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1625class Into(Expression):
1626    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1629class From(Expression):
1630    @property
1631    def name(self) -> str:
1632        return self.this.name
1633
1634    @property
1635    def alias_or_name(self) -> str:
1636        return self.this.alias_or_name
name: str
1630    @property
1631    def name(self) -> str:
1632        return self.this.name
alias_or_name: str
1634    @property
1635    def alias_or_name(self) -> str:
1636        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1639class Having(Expression):
1640    pass
key = 'having'
class Hint(Expression):
1643class Hint(Expression):
1644    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1647class JoinHint(Expression):
1648    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1651class Identifier(Expression):
1652    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1653
1654    @property
1655    def quoted(self) -> bool:
1656        return bool(self.args.get("quoted"))
1657
1658    @property
1659    def hashable_args(self) -> t.Any:
1660        return (self.this, self.quoted)
1661
1662    @property
1663    def output_name(self) -> str:
1664        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1654    @property
1655    def quoted(self) -> bool:
1656        return bool(self.args.get("quoted"))
hashable_args: Any
1658    @property
1659    def hashable_args(self) -> t.Any:
1660        return (self.this, self.quoted)
output_name: str
1662    @property
1663    def output_name(self) -> str:
1664        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):
1668class Opclass(Expression):
1669    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1672class Index(Expression):
1673    arg_types = {
1674        "this": False,
1675        "table": False,
1676        "using": False,
1677        "where": False,
1678        "columns": False,
1679        "unique": False,
1680        "primary": False,
1681        "amp": False,  # teradata
1682        "include": False,
1683        "partition_by": False,  # teradata
1684    }
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):
1687class Insert(DDL, DML):
1688    arg_types = {
1689        "with": False,
1690        "this": True,
1691        "expression": False,
1692        "conflict": False,
1693        "returning": False,
1694        "overwrite": False,
1695        "exists": False,
1696        "partition": False,
1697        "alternative": False,
1698        "where": False,
1699        "ignore": False,
1700        "by_name": False,
1701    }
1702
1703    def with_(
1704        self,
1705        alias: ExpOrStr,
1706        as_: ExpOrStr,
1707        recursive: t.Optional[bool] = None,
1708        append: bool = True,
1709        dialect: DialectType = None,
1710        copy: bool = True,
1711        **opts,
1712    ) -> Insert:
1713        """
1714        Append to or set the common table expressions.
1715
1716        Example:
1717            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1718            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1719
1720        Args:
1721            alias: the SQL code string to parse as the table name.
1722                If an `Expression` instance is passed, this is used as-is.
1723            as_: the SQL code string to parse as the table expression.
1724                If an `Expression` instance is passed, it will be used as-is.
1725            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1726            append: if `True`, add to any existing expressions.
1727                Otherwise, this resets the expressions.
1728            dialect: the dialect used to parse the input expression.
1729            copy: if `False`, modify this expression instance in-place.
1730            opts: other options to use to parse the input expressions.
1731
1732        Returns:
1733            The modified expression.
1734        """
1735        return _apply_cte_builder(
1736            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1737        )
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:
1703    def with_(
1704        self,
1705        alias: ExpOrStr,
1706        as_: ExpOrStr,
1707        recursive: t.Optional[bool] = None,
1708        append: bool = True,
1709        dialect: DialectType = None,
1710        copy: bool = True,
1711        **opts,
1712    ) -> Insert:
1713        """
1714        Append to or set the common table expressions.
1715
1716        Example:
1717            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1718            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1719
1720        Args:
1721            alias: the SQL code string to parse as the table name.
1722                If an `Expression` instance is passed, this is used as-is.
1723            as_: the SQL code string to parse as the table expression.
1724                If an `Expression` instance is passed, it will be used as-is.
1725            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1726            append: if `True`, add to any existing expressions.
1727                Otherwise, this resets the expressions.
1728            dialect: the dialect used to parse the input expression.
1729            copy: if `False`, modify this expression instance in-place.
1730            opts: other options to use to parse the input expressions.
1731
1732        Returns:
1733            The modified expression.
1734        """
1735        return _apply_cte_builder(
1736            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1737        )

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

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

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

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

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

Checks whether an expression is a star.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3567class Pivot(Expression):
3568    arg_types = {
3569        "this": False,
3570        "alias": False,
3571        "expressions": False,
3572        "field": False,
3573        "unpivot": False,
3574        "using": False,
3575        "group": False,
3576        "columns": False,
3577        "include_nulls": False,
3578    }
3579
3580    @property
3581    def unpivot(self) -> bool:
3582        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
3580    @property
3581    def unpivot(self) -> bool:
3582        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3585class Window(Condition):
3586    arg_types = {
3587        "this": True,
3588        "partition_by": False,
3589        "order": False,
3590        "spec": False,
3591        "alias": False,
3592        "over": False,
3593        "first": False,
3594    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3597class WindowSpec(Expression):
3598    arg_types = {
3599        "kind": False,
3600        "start": False,
3601        "start_side": False,
3602        "end": False,
3603        "end_side": False,
3604    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3607class Where(Expression):
3608    pass
key = 'where'
class Star(Expression):
3611class Star(Expression):
3612    arg_types = {"except": False, "replace": False}
3613
3614    @property
3615    def name(self) -> str:
3616        return "*"
3617
3618    @property
3619    def output_name(self) -> str:
3620        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3614    @property
3615    def name(self) -> str:
3616        return "*"
output_name: str
3618    @property
3619    def output_name(self) -> str:
3620        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):
3623class Parameter(Condition):
3624    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3627class SessionParameter(Condition):
3628    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3631class Placeholder(Condition):
3632    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3635class Null(Condition):
3636    arg_types: t.Dict[str, t.Any] = {}
3637
3638    @property
3639    def name(self) -> str:
3640        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3638    @property
3639    def name(self) -> str:
3640        return "NULL"
key = 'null'
class Boolean(Condition):
3643class Boolean(Condition):
3644    pass
key = 'boolean'
class DataTypeParam(Expression):
3647class DataTypeParam(Expression):
3648    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3651class DataType(Expression):
3652    arg_types = {
3653        "this": True,
3654        "expressions": False,
3655        "nested": False,
3656        "values": False,
3657        "prefix": False,
3658        "kind": False,
3659    }
3660
3661    class Type(AutoName):
3662        ARRAY = auto()
3663        AGGREGATEFUNCTION = auto()
3664        SIMPLEAGGREGATEFUNCTION = auto()
3665        BIGDECIMAL = auto()
3666        BIGINT = auto()
3667        BIGSERIAL = auto()
3668        BINARY = auto()
3669        BIT = auto()
3670        BOOLEAN = auto()
3671        BPCHAR = auto()
3672        CHAR = auto()
3673        DATE = auto()
3674        DATE32 = auto()
3675        DATEMULTIRANGE = auto()
3676        DATERANGE = auto()
3677        DATETIME = auto()
3678        DATETIME64 = auto()
3679        DECIMAL = auto()
3680        DOUBLE = auto()
3681        ENUM = auto()
3682        ENUM8 = auto()
3683        ENUM16 = auto()
3684        FIXEDSTRING = auto()
3685        FLOAT = auto()
3686        GEOGRAPHY = auto()
3687        GEOMETRY = auto()
3688        HLLSKETCH = auto()
3689        HSTORE = auto()
3690        IMAGE = auto()
3691        INET = auto()
3692        INT = auto()
3693        INT128 = auto()
3694        INT256 = auto()
3695        INT4MULTIRANGE = auto()
3696        INT4RANGE = auto()
3697        INT8MULTIRANGE = auto()
3698        INT8RANGE = auto()
3699        INTERVAL = auto()
3700        IPADDRESS = auto()
3701        IPPREFIX = auto()
3702        IPV4 = auto()
3703        IPV6 = auto()
3704        JSON = auto()
3705        JSONB = auto()
3706        LONGBLOB = auto()
3707        LONGTEXT = auto()
3708        LOWCARDINALITY = auto()
3709        MAP = auto()
3710        MEDIUMBLOB = auto()
3711        MEDIUMINT = auto()
3712        MEDIUMTEXT = auto()
3713        MONEY = auto()
3714        NCHAR = auto()
3715        NESTED = auto()
3716        NULL = auto()
3717        NULLABLE = auto()
3718        NUMMULTIRANGE = auto()
3719        NUMRANGE = auto()
3720        NVARCHAR = auto()
3721        OBJECT = auto()
3722        ROWVERSION = auto()
3723        SERIAL = auto()
3724        SET = auto()
3725        SMALLINT = auto()
3726        SMALLMONEY = auto()
3727        SMALLSERIAL = auto()
3728        STRUCT = auto()
3729        SUPER = auto()
3730        TEXT = auto()
3731        TINYBLOB = auto()
3732        TINYTEXT = auto()
3733        TIME = auto()
3734        TIMETZ = auto()
3735        TIMESTAMP = auto()
3736        TIMESTAMPLTZ = auto()
3737        TIMESTAMPTZ = auto()
3738        TIMESTAMP_S = auto()
3739        TIMESTAMP_MS = auto()
3740        TIMESTAMP_NS = auto()
3741        TINYINT = auto()
3742        TSMULTIRANGE = auto()
3743        TSRANGE = auto()
3744        TSTZMULTIRANGE = auto()
3745        TSTZRANGE = auto()
3746        UBIGINT = auto()
3747        UINT = auto()
3748        UINT128 = auto()
3749        UINT256 = auto()
3750        UMEDIUMINT = auto()
3751        UDECIMAL = auto()
3752        UNIQUEIDENTIFIER = auto()
3753        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3754        USERDEFINED = "USER-DEFINED"
3755        USMALLINT = auto()
3756        UTINYINT = auto()
3757        UUID = auto()
3758        VARBINARY = auto()
3759        VARCHAR = auto()
3760        VARIANT = auto()
3761        XML = auto()
3762        YEAR = auto()
3763
3764    TEXT_TYPES = {
3765        Type.CHAR,
3766        Type.NCHAR,
3767        Type.VARCHAR,
3768        Type.NVARCHAR,
3769        Type.TEXT,
3770    }
3771
3772    INTEGER_TYPES = {
3773        Type.INT,
3774        Type.TINYINT,
3775        Type.SMALLINT,
3776        Type.BIGINT,
3777        Type.INT128,
3778        Type.INT256,
3779        Type.BIT,
3780    }
3781
3782    FLOAT_TYPES = {
3783        Type.FLOAT,
3784        Type.DOUBLE,
3785    }
3786
3787    NUMERIC_TYPES = {
3788        *INTEGER_TYPES,
3789        *FLOAT_TYPES,
3790    }
3791
3792    TEMPORAL_TYPES = {
3793        Type.TIME,
3794        Type.TIMETZ,
3795        Type.TIMESTAMP,
3796        Type.TIMESTAMPTZ,
3797        Type.TIMESTAMPLTZ,
3798        Type.TIMESTAMP_S,
3799        Type.TIMESTAMP_MS,
3800        Type.TIMESTAMP_NS,
3801        Type.DATE,
3802        Type.DATE32,
3803        Type.DATETIME,
3804        Type.DATETIME64,
3805    }
3806
3807    @classmethod
3808    def build(
3809        cls,
3810        dtype: DATA_TYPE,
3811        dialect: DialectType = None,
3812        udt: bool = False,
3813        copy: bool = True,
3814        **kwargs,
3815    ) -> DataType:
3816        """
3817        Constructs a DataType object.
3818
3819        Args:
3820            dtype: the data type of interest.
3821            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3822            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3823                DataType, thus creating a user-defined type.
3824            copy: whether or not to copy the data type.
3825            kwargs: additional arguments to pass in the constructor of DataType.
3826
3827        Returns:
3828            The constructed DataType object.
3829        """
3830        from sqlglot import parse_one
3831
3832        if isinstance(dtype, str):
3833            if dtype.upper() == "UNKNOWN":
3834                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3835
3836            try:
3837                data_type_exp = parse_one(
3838                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3839                )
3840            except ParseError:
3841                if udt:
3842                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3843                raise
3844        elif isinstance(dtype, DataType.Type):
3845            data_type_exp = DataType(this=dtype)
3846        elif isinstance(dtype, DataType):
3847            return maybe_copy(dtype, copy)
3848        else:
3849            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3850
3851        return DataType(**{**data_type_exp.args, **kwargs})
3852
3853    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3854        """
3855        Checks whether this DataType matches one of the provided data types. Nested types or precision
3856        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3857
3858        Args:
3859            dtypes: the data types to compare this DataType to.
3860
3861        Returns:
3862            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3863        """
3864        for dtype in dtypes:
3865            other = DataType.build(dtype, copy=False, udt=True)
3866
3867            if (
3868                other.expressions
3869                or self.this == DataType.Type.USERDEFINED
3870                or other.this == DataType.Type.USERDEFINED
3871            ):
3872                matches = self == other
3873            else:
3874                matches = self.this == other.this
3875
3876            if matches:
3877                return True
3878        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>}
INTEGER_TYPES = {<Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATE: 'DATE'>}
@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:
3807    @classmethod
3808    def build(
3809        cls,
3810        dtype: DATA_TYPE,
3811        dialect: DialectType = None,
3812        udt: bool = False,
3813        copy: bool = True,
3814        **kwargs,
3815    ) -> DataType:
3816        """
3817        Constructs a DataType object.
3818
3819        Args:
3820            dtype: the data type of interest.
3821            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3822            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3823                DataType, thus creating a user-defined type.
3824            copy: whether or not to copy the data type.
3825            kwargs: additional arguments to pass in the constructor of DataType.
3826
3827        Returns:
3828            The constructed DataType object.
3829        """
3830        from sqlglot import parse_one
3831
3832        if isinstance(dtype, str):
3833            if dtype.upper() == "UNKNOWN":
3834                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3835
3836            try:
3837                data_type_exp = parse_one(
3838                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3839                )
3840            except ParseError:
3841                if udt:
3842                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3843                raise
3844        elif isinstance(dtype, DataType.Type):
3845            data_type_exp = DataType(this=dtype)
3846        elif isinstance(dtype, DataType):
3847            return maybe_copy(dtype, copy)
3848        else:
3849            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3850
3851        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:
3853    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3854        """
3855        Checks whether this DataType matches one of the provided data types. Nested types or precision
3856        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3857
3858        Args:
3859            dtypes: the data types to compare this DataType to.
3860
3861        Returns:
3862            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3863        """
3864        for dtype in dtypes:
3865            other = DataType.build(dtype, copy=False, udt=True)
3866
3867            if (
3868                other.expressions
3869                or self.this == DataType.Type.USERDEFINED
3870                or other.this == DataType.Type.USERDEFINED
3871            ):
3872                matches = self == other
3873            else:
3874                matches = self.this == other.this
3875
3876            if matches:
3877                return True
3878        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):
3661    class Type(AutoName):
3662        ARRAY = auto()
3663        AGGREGATEFUNCTION = auto()
3664        SIMPLEAGGREGATEFUNCTION = auto()
3665        BIGDECIMAL = auto()
3666        BIGINT = auto()
3667        BIGSERIAL = auto()
3668        BINARY = auto()
3669        BIT = auto()
3670        BOOLEAN = auto()
3671        BPCHAR = auto()
3672        CHAR = auto()
3673        DATE = auto()
3674        DATE32 = auto()
3675        DATEMULTIRANGE = auto()
3676        DATERANGE = auto()
3677        DATETIME = auto()
3678        DATETIME64 = auto()
3679        DECIMAL = auto()
3680        DOUBLE = auto()
3681        ENUM = auto()
3682        ENUM8 = auto()
3683        ENUM16 = auto()
3684        FIXEDSTRING = auto()
3685        FLOAT = auto()
3686        GEOGRAPHY = auto()
3687        GEOMETRY = auto()
3688        HLLSKETCH = auto()
3689        HSTORE = auto()
3690        IMAGE = auto()
3691        INET = auto()
3692        INT = auto()
3693        INT128 = auto()
3694        INT256 = auto()
3695        INT4MULTIRANGE = auto()
3696        INT4RANGE = auto()
3697        INT8MULTIRANGE = auto()
3698        INT8RANGE = auto()
3699        INTERVAL = auto()
3700        IPADDRESS = auto()
3701        IPPREFIX = auto()
3702        IPV4 = auto()
3703        IPV6 = auto()
3704        JSON = auto()
3705        JSONB = auto()
3706        LONGBLOB = auto()
3707        LONGTEXT = auto()
3708        LOWCARDINALITY = auto()
3709        MAP = auto()
3710        MEDIUMBLOB = auto()
3711        MEDIUMINT = auto()
3712        MEDIUMTEXT = auto()
3713        MONEY = auto()
3714        NCHAR = auto()
3715        NESTED = auto()
3716        NULL = auto()
3717        NULLABLE = auto()
3718        NUMMULTIRANGE = auto()
3719        NUMRANGE = auto()
3720        NVARCHAR = auto()
3721        OBJECT = auto()
3722        ROWVERSION = auto()
3723        SERIAL = auto()
3724        SET = auto()
3725        SMALLINT = auto()
3726        SMALLMONEY = auto()
3727        SMALLSERIAL = auto()
3728        STRUCT = auto()
3729        SUPER = auto()
3730        TEXT = auto()
3731        TINYBLOB = auto()
3732        TINYTEXT = auto()
3733        TIME = auto()
3734        TIMETZ = auto()
3735        TIMESTAMP = auto()
3736        TIMESTAMPLTZ = auto()
3737        TIMESTAMPTZ = auto()
3738        TIMESTAMP_S = auto()
3739        TIMESTAMP_MS = auto()
3740        TIMESTAMP_NS = auto()
3741        TINYINT = auto()
3742        TSMULTIRANGE = auto()
3743        TSRANGE = auto()
3744        TSTZMULTIRANGE = auto()
3745        TSTZRANGE = auto()
3746        UBIGINT = auto()
3747        UINT = auto()
3748        UINT128 = auto()
3749        UINT256 = auto()
3750        UMEDIUMINT = auto()
3751        UDECIMAL = auto()
3752        UNIQUEIDENTIFIER = auto()
3753        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3754        USERDEFINED = "USER-DEFINED"
3755        USMALLINT = auto()
3756        UTINYINT = auto()
3757        UUID = auto()
3758        VARBINARY = auto()
3759        VARCHAR = auto()
3760        VARIANT = auto()
3761        XML = auto()
3762        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):
3885class PseudoType(DataType):
3886    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3890class ObjectIdentifier(DataType):
3891    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3895class SubqueryPredicate(Predicate):
3896    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3899class All(SubqueryPredicate):
3900    pass
key = 'all'
class Any(SubqueryPredicate):
3903class Any(SubqueryPredicate):
3904    pass
key = 'any'
class Exists(SubqueryPredicate):
3907class Exists(SubqueryPredicate):
3908    pass
key = 'exists'
class Command(Expression):
3913class Command(Expression):
3914    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3917class Transaction(Expression):
3918    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3921class Commit(Expression):
3922    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3925class Rollback(Expression):
3926    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3929class AlterTable(Expression):
3930    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):
3933class AddConstraint(Expression):
3934    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3937class DropPartition(Expression):
3938    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3942class Binary(Condition):
3943    arg_types = {"this": True, "expression": True}
3944
3945    @property
3946    def left(self) -> Expression:
3947        return self.this
3948
3949    @property
3950    def right(self) -> Expression:
3951        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3945    @property
3946    def left(self) -> Expression:
3947        return self.this
right: Expression
3949    @property
3950    def right(self) -> Expression:
3951        return self.expression
key = 'binary'
class Add(Binary):
3954class Add(Binary):
3955    pass
key = 'add'
class Connector(Binary):
3958class Connector(Binary):
3959    pass
key = 'connector'
class And(Connector):
3962class And(Connector):
3963    pass
key = 'and'
class Or(Connector):
3966class Or(Connector):
3967    pass
key = 'or'
class BitwiseAnd(Binary):
3970class BitwiseAnd(Binary):
3971    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3974class BitwiseLeftShift(Binary):
3975    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3978class BitwiseOr(Binary):
3979    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3982class BitwiseRightShift(Binary):
3983    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3986class BitwiseXor(Binary):
3987    pass
key = 'bitwisexor'
class Div(Binary):
3990class Div(Binary):
3991    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):
3994class Overlaps(Binary):
3995    pass
key = 'overlaps'
class Dot(Binary):
3998class Dot(Binary):
3999    @property
4000    def name(self) -> str:
4001        return self.expression.name
4002
4003    @property
4004    def output_name(self) -> str:
4005        return self.name
4006
4007    @classmethod
4008    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4009        """Build a Dot object with a sequence of expressions."""
4010        if len(expressions) < 2:
4011            raise ValueError("Dot requires >= 2 expressions.")
4012
4013        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4014
4015    @property
4016    def parts(self) -> t.List[Expression]:
4017        """Return the parts of a table / column in order catalog, db, table."""
4018        this, *parts = self.flatten()
4019
4020        parts.reverse()
4021
4022        for arg in ("this", "table", "db", "catalog"):
4023            part = this.args.get(arg)
4024
4025            if isinstance(part, Expression):
4026                parts.append(part)
4027
4028        parts.reverse()
4029        return parts
name: str
3999    @property
4000    def name(self) -> str:
4001        return self.expression.name
output_name: str
4003    @property
4004    def output_name(self) -> str:
4005        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:
4007    @classmethod
4008    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4009        """Build a Dot object with a sequence of expressions."""
4010        if len(expressions) < 2:
4011            raise ValueError("Dot requires >= 2 expressions.")
4012
4013        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]
4015    @property
4016    def parts(self) -> t.List[Expression]:
4017        """Return the parts of a table / column in order catalog, db, table."""
4018        this, *parts = self.flatten()
4019
4020        parts.reverse()
4021
4022        for arg in ("this", "table", "db", "catalog"):
4023            part = this.args.get(arg)
4024
4025            if isinstance(part, Expression):
4026                parts.append(part)
4027
4028        parts.reverse()
4029        return parts

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

key = 'dot'
class DPipe(Binary):
4032class DPipe(Binary):
4033    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4036class EQ(Binary, Predicate):
4037    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4040class NullSafeEQ(Binary, Predicate):
4041    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4044class NullSafeNEQ(Binary, Predicate):
4045    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4049class PropertyEQ(Binary):
4050    pass
key = 'propertyeq'
class Distance(Binary):
4053class Distance(Binary):
4054    pass
key = 'distance'
class Escape(Binary):
4057class Escape(Binary):
4058    pass
key = 'escape'
class Glob(Binary, Predicate):
4061class Glob(Binary, Predicate):
4062    pass
key = 'glob'
class GT(Binary, Predicate):
4065class GT(Binary, Predicate):
4066    pass
key = 'gt'
class GTE(Binary, Predicate):
4069class GTE(Binary, Predicate):
4070    pass
key = 'gte'
class ILike(Binary, Predicate):
4073class ILike(Binary, Predicate):
4074    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4077class ILikeAny(Binary, Predicate):
4078    pass
key = 'ilikeany'
class IntDiv(Binary):
4081class IntDiv(Binary):
4082    pass
key = 'intdiv'
class Is(Binary, Predicate):
4085class Is(Binary, Predicate):
4086    pass
key = 'is'
class Kwarg(Binary):
4089class Kwarg(Binary):
4090    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4093class Like(Binary, Predicate):
4094    pass
key = 'like'
class LikeAny(Binary, Predicate):
4097class LikeAny(Binary, Predicate):
4098    pass
key = 'likeany'
class LT(Binary, Predicate):
4101class LT(Binary, Predicate):
4102    pass
key = 'lt'
class LTE(Binary, Predicate):
4105class LTE(Binary, Predicate):
4106    pass
key = 'lte'
class Mod(Binary):
4109class Mod(Binary):
4110    pass
key = 'mod'
class Mul(Binary):
4113class Mul(Binary):
4114    pass
key = 'mul'
class NEQ(Binary, Predicate):
4117class NEQ(Binary, Predicate):
4118    pass
key = 'neq'
class Operator(Binary):
4122class Operator(Binary):
4123    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4126class SimilarTo(Binary, Predicate):
4127    pass
key = 'similarto'
class Slice(Binary):
4130class Slice(Binary):
4131    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4134class Sub(Binary):
4135    pass
key = 'sub'
class Unary(Condition):
4140class Unary(Condition):
4141    pass
key = 'unary'
class BitwiseNot(Unary):
4144class BitwiseNot(Unary):
4145    pass
key = 'bitwisenot'
class Not(Unary):
4148class Not(Unary):
4149    pass
key = 'not'
class Paren(Unary):
4152class Paren(Unary):
4153    arg_types = {"this": True, "with": False}
4154
4155    @property
4156    def output_name(self) -> str:
4157        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4155    @property
4156    def output_name(self) -> str:
4157        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):
4160class Neg(Unary):
4161    pass
key = 'neg'
class Alias(Expression):
4164class Alias(Expression):
4165    arg_types = {"this": True, "alias": False}
4166
4167    @property
4168    def output_name(self) -> str:
4169        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4167    @property
4168    def output_name(self) -> str:
4169        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):
4174class PivotAlias(Alias):
4175    pass
key = 'pivotalias'
class Aliases(Expression):
4178class Aliases(Expression):
4179    arg_types = {"this": True, "expressions": True}
4180
4181    @property
4182    def aliases(self):
4183        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4181    @property
4182    def aliases(self):
4183        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4187class AtIndex(Expression):
4188    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4191class AtTimeZone(Expression):
4192    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4195class FromTimeZone(Expression):
4196    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4199class Between(Predicate):
4200    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4203class Bracket(Condition):
4204    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4205    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4206
4207    @property
4208    def output_name(self) -> str:
4209        if len(self.expressions) == 1:
4210            return self.expressions[0].output_name
4211
4212        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4207    @property
4208    def output_name(self) -> str:
4209        if len(self.expressions) == 1:
4210            return self.expressions[0].output_name
4211
4212        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):
4215class Distinct(Expression):
4216    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4219class In(Predicate):
4220    arg_types = {
4221        "this": True,
4222        "expressions": False,
4223        "query": False,
4224        "unnest": False,
4225        "field": False,
4226        "is_global": False,
4227    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4231class ForIn(Expression):
4232    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4235class TimeUnit(Expression):
4236    """Automatically converts unit arg into a var."""
4237
4238    arg_types = {"unit": False}
4239
4240    UNABBREVIATED_UNIT_NAME = {
4241        "D": "DAY",
4242        "H": "HOUR",
4243        "M": "MINUTE",
4244        "MS": "MILLISECOND",
4245        "NS": "NANOSECOND",
4246        "Q": "QUARTER",
4247        "S": "SECOND",
4248        "US": "MICROSECOND",
4249        "W": "WEEK",
4250        "Y": "YEAR",
4251    }
4252
4253    VAR_LIKE = (Column, Literal, Var)
4254
4255    def __init__(self, **args):
4256        unit = args.get("unit")
4257        if isinstance(unit, self.VAR_LIKE):
4258            args["unit"] = Var(
4259                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4260            )
4261        elif isinstance(unit, Week):
4262            unit.set("this", Var(this=unit.this.name.upper()))
4263
4264        super().__init__(**args)
4265
4266    @property
4267    def unit(self) -> t.Optional[Var]:
4268        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4255    def __init__(self, **args):
4256        unit = args.get("unit")
4257        if isinstance(unit, self.VAR_LIKE):
4258            args["unit"] = Var(
4259                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4260            )
4261        elif isinstance(unit, Week):
4262            unit.set("this", Var(this=unit.this.name.upper()))
4263
4264        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]
4266    @property
4267    def unit(self) -> t.Optional[Var]:
4268        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4271class IntervalOp(TimeUnit):
4272    arg_types = {"unit": True, "expression": True}
4273
4274    def interval(self):
4275        return Interval(
4276            this=self.expression.copy(),
4277            unit=self.unit.copy(),
4278        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4274    def interval(self):
4275        return Interval(
4276            this=self.expression.copy(),
4277            unit=self.unit.copy(),
4278        )
key = 'intervalop'
class IntervalSpan(DataType):
4284class IntervalSpan(DataType):
4285    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4288class Interval(TimeUnit):
4289    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4292class IgnoreNulls(Expression):
4293    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4296class RespectNulls(Expression):
4297    pass
key = 'respectnulls'
class HavingMax(Expression):
4301class HavingMax(Expression):
4302    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4306class Func(Condition):
4307    """
4308    The base class for all function expressions.
4309
4310    Attributes:
4311        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4312            treated as a variable length argument and the argument's value will be stored as a list.
4313        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4314            for this function expression. These values are used to map this node to a name during parsing
4315            as well as to provide the function's name during SQL string generation. By default the SQL
4316            name is set to the expression's class name transformed to snake case.
4317    """
4318
4319    is_var_len_args = False
4320
4321    @classmethod
4322    def from_arg_list(cls, args):
4323        if cls.is_var_len_args:
4324            all_arg_keys = list(cls.arg_types)
4325            # If this function supports variable length argument treat the last argument as such.
4326            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4327            num_non_var = len(non_var_len_arg_keys)
4328
4329            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4330            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4331        else:
4332            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4333
4334        return cls(**args_dict)
4335
4336    @classmethod
4337    def sql_names(cls):
4338        if cls is Func:
4339            raise NotImplementedError(
4340                "SQL name is only supported by concrete function implementations"
4341            )
4342        if "_sql_names" not in cls.__dict__:
4343            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4344        return cls._sql_names
4345
4346    @classmethod
4347    def sql_name(cls):
4348        return cls.sql_names()[0]
4349
4350    @classmethod
4351    def default_parser_mappings(cls):
4352        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):
4321    @classmethod
4322    def from_arg_list(cls, args):
4323        if cls.is_var_len_args:
4324            all_arg_keys = list(cls.arg_types)
4325            # If this function supports variable length argument treat the last argument as such.
4326            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4327            num_non_var = len(non_var_len_arg_keys)
4328
4329            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4330            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4331        else:
4332            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4333
4334        return cls(**args_dict)
@classmethod
def sql_names(cls):
4336    @classmethod
4337    def sql_names(cls):
4338        if cls is Func:
4339            raise NotImplementedError(
4340                "SQL name is only supported by concrete function implementations"
4341            )
4342        if "_sql_names" not in cls.__dict__:
4343            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4344        return cls._sql_names
@classmethod
def sql_name(cls):
4346    @classmethod
4347    def sql_name(cls):
4348        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4350    @classmethod
4351    def default_parser_mappings(cls):
4352        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4355class AggFunc(Func):
4356    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4359class ParameterizedAgg(AggFunc):
4360    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4363class Abs(Func):
4364    pass
key = 'abs'
class ArgMax(AggFunc):
4367class ArgMax(AggFunc):
4368    arg_types = {"this": True, "expression": True, "count": False}
4369    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4372class ArgMin(AggFunc):
4373    arg_types = {"this": True, "expression": True, "count": False}
4374    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4377class ApproxTopK(AggFunc):
4378    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4381class Flatten(Func):
4382    pass
key = 'flatten'
class Transform(Func):
4386class Transform(Func):
4387    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4390class Anonymous(Func):
4391    arg_types = {"this": True, "expressions": False}
4392    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4395class AnonymousAggFunc(AggFunc):
4396    arg_types = {"this": True, "expressions": False}
4397    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4401class CombinedAggFunc(AnonymousAggFunc):
4402    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4405class CombinedParameterizedAgg(ParameterizedAgg):
4406    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):
4411class Hll(AggFunc):
4412    arg_types = {"this": True, "expressions": False}
4413    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4416class ApproxDistinct(AggFunc):
4417    arg_types = {"this": True, "accuracy": False}
4418    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4421class Array(Func):
4422    arg_types = {"expressions": False}
4423    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4427class ToArray(Func):
4428    pass
key = 'toarray'
class ToChar(Func):
4433class ToChar(Func):
4434    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4437class GenerateSeries(Func):
4438    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4441class ArrayAgg(AggFunc):
4442    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4445class ArrayUniqueAgg(AggFunc):
4446    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4449class ArrayAll(Func):
4450    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4453class ArrayAny(Func):
4454    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4457class ArrayConcat(Func):
4458    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4459    arg_types = {"this": True, "expressions": False}
4460    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4463class ArrayContains(Binary, Func):
4464    pass
key = 'arraycontains'
class ArrayContained(Binary):
4467class ArrayContained(Binary):
4468    pass
key = 'arraycontained'
class ArrayFilter(Func):
4471class ArrayFilter(Func):
4472    arg_types = {"this": True, "expression": True}
4473    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4476class ArrayJoin(Func):
4477    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4480class ArrayOverlaps(Binary, Func):
4481    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4484class ArraySize(Func):
4485    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4488class ArraySort(Func):
4489    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4492class ArraySum(Func):
4493    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4496class ArrayUnionAgg(AggFunc):
4497    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4500class Avg(AggFunc):
4501    pass
key = 'avg'
class AnyValue(AggFunc):
4504class AnyValue(AggFunc):
4505    pass
key = 'anyvalue'
class Lag(AggFunc):
4508class Lag(AggFunc):
4509    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4512class Lead(AggFunc):
4513    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4518class First(AggFunc):
4519    pass
key = 'first'
class Last(AggFunc):
4522class Last(AggFunc):
4523    pass
key = 'last'
class FirstValue(AggFunc):
4526class FirstValue(AggFunc):
4527    pass
key = 'firstvalue'
class LastValue(AggFunc):
4530class LastValue(AggFunc):
4531    pass
key = 'lastvalue'
class NthValue(AggFunc):
4534class NthValue(AggFunc):
4535    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4538class Case(Func):
4539    arg_types = {"this": False, "ifs": True, "default": False}
4540
4541    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4542        instance = maybe_copy(self, copy)
4543        instance.append(
4544            "ifs",
4545            If(
4546                this=maybe_parse(condition, copy=copy, **opts),
4547                true=maybe_parse(then, copy=copy, **opts),
4548            ),
4549        )
4550        return instance
4551
4552    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4553        instance = maybe_copy(self, copy)
4554        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4555        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:
4541    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4542        instance = maybe_copy(self, copy)
4543        instance.append(
4544            "ifs",
4545            If(
4546                this=maybe_parse(condition, copy=copy, **opts),
4547                true=maybe_parse(then, copy=copy, **opts),
4548            ),
4549        )
4550        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4552    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4553        instance = maybe_copy(self, copy)
4554        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4555        return instance
key = 'case'
class Cast(Func):
4558class Cast(Func):
4559    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4560
4561    @property
4562    def name(self) -> str:
4563        return self.this.name
4564
4565    @property
4566    def to(self) -> DataType:
4567        return self.args["to"]
4568
4569    @property
4570    def output_name(self) -> str:
4571        return self.name
4572
4573    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4574        """
4575        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4576        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4577        array<int> != array<float>.
4578
4579        Args:
4580            dtypes: the data types to compare this Cast's DataType to.
4581
4582        Returns:
4583            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4584        """
4585        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4561    @property
4562    def name(self) -> str:
4563        return self.this.name
to: DataType
4565    @property
4566    def to(self) -> DataType:
4567        return self.args["to"]
output_name: str
4569    @property
4570    def output_name(self) -> str:
4571        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:
4573    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4574        """
4575        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4576        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4577        array<int> != array<float>.
4578
4579        Args:
4580            dtypes: the data types to compare this Cast's DataType to.
4581
4582        Returns:
4583            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4584        """
4585        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):
4588class TryCast(Cast):
4589    pass
key = 'trycast'
class CastToStrType(Func):
4592class CastToStrType(Func):
4593    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4596class Collate(Binary, Func):
4597    pass
key = 'collate'
class Ceil(Func):
4600class Ceil(Func):
4601    arg_types = {"this": True, "decimals": False}
4602    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4605class Coalesce(Func):
4606    arg_types = {"this": True, "expressions": False}
4607    is_var_len_args = True
4608    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4611class Chr(Func):
4612    arg_types = {"this": True, "charset": False, "expressions": False}
4613    is_var_len_args = True
4614    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4617class Concat(Func):
4618    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4619    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4622class ConcatWs(Concat):
4623    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4626class Count(AggFunc):
4627    arg_types = {"this": False, "expressions": False}
4628    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4631class CountIf(AggFunc):
4632    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4636class Cbrt(Func):
4637    pass
key = 'cbrt'
class CurrentDate(Func):
4640class CurrentDate(Func):
4641    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4644class CurrentDatetime(Func):
4645    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4648class CurrentTime(Func):
4649    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4652class CurrentTimestamp(Func):
4653    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4656class CurrentUser(Func):
4657    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4660class DateAdd(Func, IntervalOp):
4661    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4664class DateSub(Func, IntervalOp):
4665    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4668class DateDiff(Func, TimeUnit):
4669    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4670    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4673class DateTrunc(Func):
4674    arg_types = {"unit": True, "this": True, "zone": False}
4675
4676    def __init__(self, **args):
4677        unit = args.get("unit")
4678        if isinstance(unit, TimeUnit.VAR_LIKE):
4679            args["unit"] = Literal.string(
4680                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4681            )
4682        elif isinstance(unit, Week):
4683            unit.set("this", Literal.string(unit.this.name.upper()))
4684
4685        super().__init__(**args)
4686
4687    @property
4688    def unit(self) -> Expression:
4689        return self.args["unit"]
DateTrunc(**args)
4676    def __init__(self, **args):
4677        unit = args.get("unit")
4678        if isinstance(unit, TimeUnit.VAR_LIKE):
4679            args["unit"] = Literal.string(
4680                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4681            )
4682        elif isinstance(unit, Week):
4683            unit.set("this", Literal.string(unit.this.name.upper()))
4684
4685        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4687    @property
4688    def unit(self) -> Expression:
4689        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4692class DatetimeAdd(Func, IntervalOp):
4693    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4696class DatetimeSub(Func, IntervalOp):
4697    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4700class DatetimeDiff(Func, TimeUnit):
4701    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4704class DatetimeTrunc(Func, TimeUnit):
4705    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4708class DayOfWeek(Func):
4709    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4712class DayOfMonth(Func):
4713    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4716class DayOfYear(Func):
4717    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4720class ToDays(Func):
4721    pass
key = 'todays'
class WeekOfYear(Func):
4724class WeekOfYear(Func):
4725    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4728class MonthsBetween(Func):
4729    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4732class LastDay(Func, TimeUnit):
4733    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4734    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4737class Extract(Func):
4738    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4741class Timestamp(Func):
4742    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4745class TimestampAdd(Func, TimeUnit):
4746    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4749class TimestampSub(Func, TimeUnit):
4750    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4753class TimestampDiff(Func, TimeUnit):
4754    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4755    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4758class TimestampTrunc(Func, TimeUnit):
4759    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4762class TimeAdd(Func, TimeUnit):
4763    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4766class TimeSub(Func, TimeUnit):
4767    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4770class TimeDiff(Func, TimeUnit):
4771    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4774class TimeTrunc(Func, TimeUnit):
4775    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4778class DateFromParts(Func):
4779    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4780    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4783class TimeFromParts(Func):
4784    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4785    arg_types = {
4786        "hour": True,
4787        "min": True,
4788        "sec": True,
4789        "nano": False,
4790        "fractions": False,
4791        "precision": False,
4792    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4795class DateStrToDate(Func):
4796    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4799class DateToDateStr(Func):
4800    pass
key = 'datetodatestr'
class DateToDi(Func):
4803class DateToDi(Func):
4804    pass
key = 'datetodi'
class Date(Func):
4808class Date(Func):
4809    arg_types = {"this": False, "zone": False, "expressions": False}
4810    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4813class Day(Func):
4814    pass
key = 'day'
class Decode(Func):
4817class Decode(Func):
4818    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4821class DiToDate(Func):
4822    pass
key = 'ditodate'
class Encode(Func):
4825class Encode(Func):
4826    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4829class Exp(Func):
4830    pass
key = 'exp'
class Explode(Func):
4834class Explode(Func):
4835    arg_types = {"this": True, "expressions": False}
4836    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4839class ExplodeOuter(Explode):
4840    pass
key = 'explodeouter'
class Posexplode(Explode):
4843class Posexplode(Explode):
4844    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
4847class PosexplodeOuter(Posexplode, ExplodeOuter):
4848    pass
key = 'posexplodeouter'
class Floor(Func):
4851class Floor(Func):
4852    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4855class FromBase64(Func):
4856    pass
key = 'frombase64'
class ToBase64(Func):
4859class ToBase64(Func):
4860    pass
key = 'tobase64'
class Greatest(Func):
4863class Greatest(Func):
4864    arg_types = {"this": True, "expressions": False}
4865    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4868class GroupConcat(AggFunc):
4869    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4872class Hex(Func):
4873    pass
key = 'hex'
class Xor(Connector, Func):
4876class Xor(Connector, Func):
4877    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4880class If(Func):
4881    arg_types = {"this": True, "true": True, "false": False}
4882    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4885class Nullif(Func):
4886    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4889class Initcap(Func):
4890    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4893class IsNan(Func):
4894    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4897class IsInf(Func):
4898    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
4901class JSONPath(Expression):
4902    arg_types = {"expressions": True}
4903
4904    @property
4905    def output_name(self) -> str:
4906        last_segment = self.expressions[-1].this
4907        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
4904    @property
4905    def output_name(self) -> str:
4906        last_segment = self.expressions[-1].this
4907        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):
4910class JSONPathPart(Expression):
4911    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
4914class JSONPathFilter(JSONPathPart):
4915    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
4918class JSONPathKey(JSONPathPart):
4919    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
4922class JSONPathRecursive(JSONPathPart):
4923    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
4926class JSONPathRoot(JSONPathPart):
4927    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
4930class JSONPathScript(JSONPathPart):
4931    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
4934class JSONPathSlice(JSONPathPart):
4935    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
4938class JSONPathSelector(JSONPathPart):
4939    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
4942class JSONPathSubscript(JSONPathPart):
4943    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
4946class JSONPathUnion(JSONPathPart):
4947    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
4950class JSONPathWildcard(JSONPathPart):
4951    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
4954class FormatJson(Expression):
4955    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4958class JSONKeyValue(Expression):
4959    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4962class JSONObject(Func):
4963    arg_types = {
4964        "expressions": False,
4965        "null_handling": False,
4966        "unique_keys": False,
4967        "return_type": False,
4968        "encoding": False,
4969    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
4972class JSONObjectAgg(AggFunc):
4973    arg_types = {
4974        "expressions": False,
4975        "null_handling": False,
4976        "unique_keys": False,
4977        "return_type": False,
4978        "encoding": False,
4979    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
4983class JSONArray(Func):
4984    arg_types = {
4985        "expressions": True,
4986        "null_handling": False,
4987        "return_type": False,
4988        "strict": False,
4989    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4993class JSONArrayAgg(Func):
4994    arg_types = {
4995        "this": True,
4996        "order": False,
4997        "null_handling": False,
4998        "return_type": False,
4999        "strict": False,
5000    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5005class JSONColumnDef(Expression):
5006    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):
5009class JSONSchema(Expression):
5010    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5014class JSONTable(Func):
5015    arg_types = {
5016        "this": True,
5017        "schema": True,
5018        "path": False,
5019        "error_handling": False,
5020        "empty_handling": False,
5021    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5024class OpenJSONColumnDef(Expression):
5025    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):
5028class OpenJSON(Func):
5029    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5032class JSONBContains(Binary):
5033    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5036class JSONExtract(Binary, Func):
5037    arg_types = {"this": True, "expression": True, "expressions": False}
5038    _sql_names = ["JSON_EXTRACT"]
5039    is_var_len_args = True
5040
5041    @property
5042    def output_name(self) -> str:
5043        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'expressions': False}
is_var_len_args = True
output_name: str
5041    @property
5042    def output_name(self) -> str:
5043        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):
5046class JSONExtractScalar(Binary, Func):
5047    arg_types = {"this": True, "expression": True, "expressions": False}
5048    _sql_names = ["JSON_EXTRACT_SCALAR"]
5049    is_var_len_args = True
5050
5051    @property
5052    def output_name(self) -> str:
5053        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'expressions': False}
is_var_len_args = True
output_name: str
5051    @property
5052    def output_name(self) -> str:
5053        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):
5056class JSONBExtract(Binary, Func):
5057    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5060class JSONBExtractScalar(Binary, Func):
5061    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5064class JSONFormat(Func):
5065    arg_types = {"this": False, "options": False}
5066    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5070class JSONArrayContains(Binary, Predicate, Func):
5071    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5074class ParseJSON(Func):
5075    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5076    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5077    arg_types = {"this": True, "expressions": False}
5078    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5081class Least(Func):
5082    arg_types = {"this": True, "expressions": False}
5083    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5086class Left(Func):
5087    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5094class Length(Func):
5095    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5098class Levenshtein(Func):
5099    arg_types = {
5100        "this": True,
5101        "expression": False,
5102        "ins_cost": False,
5103        "del_cost": False,
5104        "sub_cost": False,
5105    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5108class Ln(Func):
5109    pass
key = 'ln'
class Log(Func):
5112class Log(Func):
5113    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5116class Log2(Func):
5117    pass
key = 'log2'
class Log10(Func):
5120class Log10(Func):
5121    pass
key = 'log10'
class LogicalOr(AggFunc):
5124class LogicalOr(AggFunc):
5125    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5128class LogicalAnd(AggFunc):
5129    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5132class Lower(Func):
5133    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5136class Map(Func):
5137    arg_types = {"keys": False, "values": False}
5138
5139    @property
5140    def keys(self) -> t.List[Expression]:
5141        keys = self.args.get("keys")
5142        return keys.expressions if keys else []
5143
5144    @property
5145    def values(self) -> t.List[Expression]:
5146        values = self.args.get("values")
5147        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5139    @property
5140    def keys(self) -> t.List[Expression]:
5141        keys = self.args.get("keys")
5142        return keys.expressions if keys else []
values: List[Expression]
5144    @property
5145    def values(self) -> t.List[Expression]:
5146        values = self.args.get("values")
5147        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5150class MapFromEntries(Func):
5151    pass
key = 'mapfromentries'
class StarMap(Func):
5154class StarMap(Func):
5155    pass
key = 'starmap'
class VarMap(Func):
5158class VarMap(Func):
5159    arg_types = {"keys": True, "values": True}
5160    is_var_len_args = True
5161
5162    @property
5163    def keys(self) -> t.List[Expression]:
5164        return self.args["keys"].expressions
5165
5166    @property
5167    def values(self) -> t.List[Expression]:
5168        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5162    @property
5163    def keys(self) -> t.List[Expression]:
5164        return self.args["keys"].expressions
values: List[Expression]
5166    @property
5167    def values(self) -> t.List[Expression]:
5168        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5172class MatchAgainst(Func):
5173    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5176class Max(AggFunc):
5177    arg_types = {"this": True, "expressions": False}
5178    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5181class MD5(Func):
5182    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5186class MD5Digest(Func):
5187    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5190class Min(AggFunc):
5191    arg_types = {"this": True, "expressions": False}
5192    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5195class Month(Func):
5196    pass
key = 'month'
class Nvl2(Func):
5199class Nvl2(Func):
5200    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5204class Predict(Func):
5205    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5208class Pow(Binary, Func):
5209    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5212class PercentileCont(AggFunc):
5213    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5216class PercentileDisc(AggFunc):
5217    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5220class Quantile(AggFunc):
5221    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5224class ApproxQuantile(Quantile):
5225    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):
5228class Rand(Func):
5229    _sql_names = ["RAND", "RANDOM"]
5230    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5233class Randn(Func):
5234    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5237class RangeN(Func):
5238    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5241class ReadCSV(Func):
5242    _sql_names = ["READ_CSV"]
5243    is_var_len_args = True
5244    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5247class Reduce(Func):
5248    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):
5251class RegexpExtract(Func):
5252    arg_types = {
5253        "this": True,
5254        "expression": True,
5255        "position": False,
5256        "occurrence": False,
5257        "parameters": False,
5258        "group": False,
5259    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5262class RegexpReplace(Func):
5263    arg_types = {
5264        "this": True,
5265        "expression": True,
5266        "replacement": False,
5267        "position": False,
5268        "occurrence": False,
5269        "parameters": False,
5270        "modifiers": False,
5271    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5274class RegexpLike(Binary, Func):
5275    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5278class RegexpILike(Binary, Func):
5279    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5284class RegexpSplit(Func):
5285    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5288class Repeat(Func):
5289    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5294class Round(Func):
5295    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5298class RowNumber(Func):
5299    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5302class SafeDivide(Func):
5303    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5306class SHA(Func):
5307    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5310class SHA2(Func):
5311    _sql_names = ["SHA2"]
5312    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5315class SortArray(Func):
5316    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5319class Split(Func):
5320    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5325class Substring(Func):
5326    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5329class StandardHash(Func):
5330    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5333class StartsWith(Func):
5334    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5335    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5338class StrPosition(Func):
5339    arg_types = {
5340        "this": True,
5341        "substr": True,
5342        "position": False,
5343        "instance": False,
5344    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5347class StrToDate(Func):
5348    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5351class StrToTime(Func):
5352    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5357class StrToUnix(Func):
5358    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5363class StrToMap(Func):
5364    arg_types = {
5365        "this": True,
5366        "pair_delim": False,
5367        "key_value_delim": False,
5368        "duplicate_resolution_callback": False,
5369    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5372class NumberToStr(Func):
5373    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5376class FromBase(Func):
5377    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5380class Struct(Func):
5381    arg_types = {"expressions": False}
5382    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5385class StructExtract(Func):
5386    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5391class Stuff(Func):
5392    _sql_names = ["STUFF", "INSERT"]
5393    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):
5396class Sum(AggFunc):
5397    pass
key = 'sum'
class Sqrt(Func):
5400class Sqrt(Func):
5401    pass
key = 'sqrt'
class Stddev(AggFunc):
5404class Stddev(AggFunc):
5405    pass
key = 'stddev'
class StddevPop(AggFunc):
5408class StddevPop(AggFunc):
5409    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5412class StddevSamp(AggFunc):
5413    pass
key = 'stddevsamp'
class TimeToStr(Func):
5416class TimeToStr(Func):
5417    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5420class TimeToTimeStr(Func):
5421    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5424class TimeToUnix(Func):
5425    pass
key = 'timetounix'
class TimeStrToDate(Func):
5428class TimeStrToDate(Func):
5429    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5432class TimeStrToTime(Func):
5433    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5436class TimeStrToUnix(Func):
5437    pass
key = 'timestrtounix'
class Trim(Func):
5440class Trim(Func):
5441    arg_types = {
5442        "this": True,
5443        "expression": False,
5444        "position": False,
5445        "collation": False,
5446    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5449class TsOrDsAdd(Func, TimeUnit):
5450    # return_type is used to correctly cast the arguments of this expression when transpiling it
5451    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5452
5453    @property
5454    def return_type(self) -> DataType:
5455        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
5453    @property
5454    def return_type(self) -> DataType:
5455        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5458class TsOrDsDiff(Func, TimeUnit):
5459    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5462class TsOrDsToDateStr(Func):
5463    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5466class TsOrDsToDate(Func):
5467    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5470class TsOrDsToTime(Func):
5471    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5474class TsOrDiToDi(Func):
5475    pass
key = 'tsorditodi'
class Unhex(Func):
5478class Unhex(Func):
5479    pass
key = 'unhex'
class UnixDate(Func):
5483class UnixDate(Func):
5484    pass
key = 'unixdate'
class UnixToStr(Func):
5487class UnixToStr(Func):
5488    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5493class UnixToTime(Func):
5494    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5495
5496    SECONDS = Literal.number(0)
5497    DECIS = Literal.number(1)
5498    CENTIS = Literal.number(2)
5499    MILLIS = Literal.number(3)
5500    DECIMILLIS = Literal.number(4)
5501    CENTIMILLIS = Literal.number(5)
5502    MICROS = Literal.number(6)
5503    DECIMICROS = Literal.number(7)
5504    CENTIMICROS = Literal.number(8)
5505    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):
5508class UnixToTimeStr(Func):
5509    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5512class TimestampFromParts(Func):
5513    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5514    arg_types = {
5515        "year": True,
5516        "month": True,
5517        "day": True,
5518        "hour": True,
5519        "min": True,
5520        "sec": True,
5521        "nano": False,
5522        "zone": False,
5523        "milli": False,
5524    }
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):
5527class Upper(Func):
5528    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5531class Variance(AggFunc):
5532    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5535class VariancePop(AggFunc):
5536    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5539class Week(Func):
5540    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5543class XMLTable(Func):
5544    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):
5547class Year(Func):
5548    pass
key = 'year'
class Use(Expression):
5551class Use(Expression):
5552    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5555class Merge(Expression):
5556    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):
5559class When(Func):
5560    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):
5565class NextValueFor(Func):
5566    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 'Cbrt'>, <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'>, 'CBRT': <class 'Cbrt'>, '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'>, 'IIF': <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:
5606def maybe_parse(
5607    sql_or_expression: ExpOrStr,
5608    *,
5609    into: t.Optional[IntoType] = None,
5610    dialect: DialectType = None,
5611    prefix: t.Optional[str] = None,
5612    copy: bool = False,
5613    **opts,
5614) -> Expression:
5615    """Gracefully handle a possible string or expression.
5616
5617    Example:
5618        >>> maybe_parse("1")
5619        Literal(this=1, is_string=False)
5620        >>> maybe_parse(to_identifier("x"))
5621        Identifier(this=x, quoted=False)
5622
5623    Args:
5624        sql_or_expression: the SQL code string or an expression
5625        into: the SQLGlot Expression to parse into
5626        dialect: the dialect used to parse the input expressions (in the case that an
5627            input expression is a SQL string).
5628        prefix: a string to prefix the sql with before it gets parsed
5629            (automatically includes a space)
5630        copy: whether or not to copy the expression.
5631        **opts: other options to use to parse the input expressions (again, in the case
5632            that an input expression is a SQL string).
5633
5634    Returns:
5635        Expression: the parsed or given expression.
5636    """
5637    if isinstance(sql_or_expression, Expression):
5638        if copy:
5639            return sql_or_expression.copy()
5640        return sql_or_expression
5641
5642    if sql_or_expression is None:
5643        raise ParseError("SQL cannot be None")
5644
5645    import sqlglot
5646
5647    sql = str(sql_or_expression)
5648    if prefix:
5649        sql = f"{prefix} {sql}"
5650
5651    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):
5664def maybe_copy(instance, copy=True):
5665    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:
5879def union(
5880    left: ExpOrStr,
5881    right: ExpOrStr,
5882    distinct: bool = True,
5883    dialect: DialectType = None,
5884    copy: bool = True,
5885    **opts,
5886) -> Union:
5887    """
5888    Initializes a syntax tree from one UNION expression.
5889
5890    Example:
5891        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5892        'SELECT * FROM foo UNION SELECT * FROM bla'
5893
5894    Args:
5895        left: the SQL code string corresponding to the left-hand side.
5896            If an `Expression` instance is passed, it will be used as-is.
5897        right: the SQL code string corresponding to the right-hand side.
5898            If an `Expression` instance is passed, it will be used as-is.
5899        distinct: set the DISTINCT flag if and only if this is true.
5900        dialect: the dialect used to parse the input expression.
5901        copy: whether or not to copy the expression.
5902        opts: other options to use to parse the input expressions.
5903
5904    Returns:
5905        The new Union instance.
5906    """
5907    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5908    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5909
5910    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:
5913def intersect(
5914    left: ExpOrStr,
5915    right: ExpOrStr,
5916    distinct: bool = True,
5917    dialect: DialectType = None,
5918    copy: bool = True,
5919    **opts,
5920) -> Intersect:
5921    """
5922    Initializes a syntax tree from one INTERSECT expression.
5923
5924    Example:
5925        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5926        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5927
5928    Args:
5929        left: the SQL code string corresponding to the left-hand side.
5930            If an `Expression` instance is passed, it will be used as-is.
5931        right: the SQL code string corresponding to the right-hand side.
5932            If an `Expression` instance is passed, it will be used as-is.
5933        distinct: set the DISTINCT flag if and only if this is true.
5934        dialect: the dialect used to parse the input expression.
5935        copy: whether or not to copy the expression.
5936        opts: other options to use to parse the input expressions.
5937
5938    Returns:
5939        The new Intersect instance.
5940    """
5941    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5942    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5943
5944    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:
5947def except_(
5948    left: ExpOrStr,
5949    right: ExpOrStr,
5950    distinct: bool = True,
5951    dialect: DialectType = None,
5952    copy: bool = True,
5953    **opts,
5954) -> Except:
5955    """
5956    Initializes a syntax tree from one EXCEPT expression.
5957
5958    Example:
5959        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5960        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5961
5962    Args:
5963        left: the SQL code string corresponding to the left-hand side.
5964            If an `Expression` instance is passed, it will be used as-is.
5965        right: the SQL code string corresponding to the right-hand side.
5966            If an `Expression` instance is passed, it will be used as-is.
5967        distinct: set the DISTINCT flag if and only if this is true.
5968        dialect: the dialect used to parse the input expression.
5969        copy: whether or not to copy the expression.
5970        opts: other options to use to parse the input expressions.
5971
5972    Returns:
5973        The new Except instance.
5974    """
5975    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5976    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5977
5978    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:
5981def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5982    """
5983    Initializes a syntax tree from one or multiple SELECT expressions.
5984
5985    Example:
5986        >>> select("col1", "col2").from_("tbl").sql()
5987        'SELECT col1, col2 FROM tbl'
5988
5989    Args:
5990        *expressions: the SQL code string to parse as the expressions of a
5991            SELECT statement. If an Expression instance is passed, this is used as-is.
5992        dialect: the dialect used to parse the input expressions (in the case that an
5993            input expression is a SQL string).
5994        **opts: other options to use to parse the input expressions (again, in the case
5995            that an input expression is a SQL string).
5996
5997    Returns:
5998        Select: the syntax tree for the SELECT statement.
5999    """
6000    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:
6003def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6004    """
6005    Initializes a syntax tree from a FROM expression.
6006
6007    Example:
6008        >>> from_("tbl").select("col1", "col2").sql()
6009        'SELECT col1, col2 FROM tbl'
6010
6011    Args:
6012        *expression: the SQL code string to parse as the FROM expressions of a
6013            SELECT statement. If an Expression instance is passed, this is used as-is.
6014        dialect: the dialect used to parse the input expression (in the case that the
6015            input expression is a SQL string).
6016        **opts: other options to use to parse the input expressions (again, in the case
6017            that the input expression is a SQL string).
6018
6019    Returns:
6020        Select: the syntax tree for the SELECT statement.
6021    """
6022    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:
6025def update(
6026    table: str | Table,
6027    properties: dict,
6028    where: t.Optional[ExpOrStr] = None,
6029    from_: t.Optional[ExpOrStr] = None,
6030    dialect: DialectType = None,
6031    **opts,
6032) -> Update:
6033    """
6034    Creates an update statement.
6035
6036    Example:
6037        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6038        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6039
6040    Args:
6041        *properties: dictionary of properties to set which are
6042            auto converted to sql objects eg None -> NULL
6043        where: sql conditional parsed into a WHERE statement
6044        from_: sql statement parsed into a FROM statement
6045        dialect: the dialect used to parse the input expressions.
6046        **opts: other options to use to parse the input expressions.
6047
6048    Returns:
6049        Update: the syntax tree for the UPDATE statement.
6050    """
6051    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6052    update_expr.set(
6053        "expressions",
6054        [
6055            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6056            for k, v in properties.items()
6057        ],
6058    )
6059    if from_:
6060        update_expr.set(
6061            "from",
6062            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6063        )
6064    if isinstance(where, Condition):
6065        where = Where(this=where)
6066    if where:
6067        update_expr.set(
6068            "where",
6069            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6070        )
6071    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:
6074def delete(
6075    table: ExpOrStr,
6076    where: t.Optional[ExpOrStr] = None,
6077    returning: t.Optional[ExpOrStr] = None,
6078    dialect: DialectType = None,
6079    **opts,
6080) -> Delete:
6081    """
6082    Builds a delete statement.
6083
6084    Example:
6085        >>> delete("my_table", where="id > 1").sql()
6086        'DELETE FROM my_table WHERE id > 1'
6087
6088    Args:
6089        where: sql conditional parsed into a WHERE statement
6090        returning: sql conditional parsed into a RETURNING statement
6091        dialect: the dialect used to parse the input expressions.
6092        **opts: other options to use to parse the input expressions.
6093
6094    Returns:
6095        Delete: the syntax tree for the DELETE statement.
6096    """
6097    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6098    if where:
6099        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6100    if returning:
6101        delete_expr = t.cast(
6102            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6103        )
6104    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:
6107def insert(
6108    expression: ExpOrStr,
6109    into: ExpOrStr,
6110    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6111    overwrite: t.Optional[bool] = None,
6112    returning: t.Optional[ExpOrStr] = None,
6113    dialect: DialectType = None,
6114    copy: bool = True,
6115    **opts,
6116) -> Insert:
6117    """
6118    Builds an INSERT statement.
6119
6120    Example:
6121        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6122        'INSERT INTO tbl VALUES (1, 2, 3)'
6123
6124    Args:
6125        expression: the sql string or expression of the INSERT statement
6126        into: the tbl to insert data to.
6127        columns: optionally the table's column names.
6128        overwrite: whether to INSERT OVERWRITE or not.
6129        returning: sql conditional parsed into a RETURNING statement
6130        dialect: the dialect used to parse the input expressions.
6131        copy: whether or not to copy the expression.
6132        **opts: other options to use to parse the input expressions.
6133
6134    Returns:
6135        Insert: the syntax tree for the INSERT statement.
6136    """
6137    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6138    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6139
6140    if columns:
6141        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6142
6143    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6144
6145    if returning:
6146        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6147
6148    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:
6151def condition(
6152    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6153) -> Condition:
6154    """
6155    Initialize a logical condition expression.
6156
6157    Example:
6158        >>> condition("x=1").sql()
6159        'x = 1'
6160
6161        This is helpful for composing larger logical syntax trees:
6162        >>> where = condition("x=1")
6163        >>> where = where.and_("y=1")
6164        >>> Select().from_("tbl").select("*").where(where).sql()
6165        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6166
6167    Args:
6168        *expression: the SQL code string to parse.
6169            If an Expression instance is passed, this is used as-is.
6170        dialect: the dialect used to parse the input expression (in the case that the
6171            input expression is a SQL string).
6172        copy: Whether or not to copy `expression` (only applies to expressions).
6173        **opts: other options to use to parse the input expressions (again, in the case
6174            that the input expression is a SQL string).
6175
6176    Returns:
6177        The new Condition instance
6178    """
6179    return maybe_parse(
6180        expression,
6181        into=Condition,
6182        dialect=dialect,
6183        copy=copy,
6184        **opts,
6185    )

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:
6188def and_(
6189    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6190) -> Condition:
6191    """
6192    Combine multiple conditions with an AND logical operator.
6193
6194    Example:
6195        >>> and_("x=1", and_("y=1", "z=1")).sql()
6196        'x = 1 AND (y = 1 AND z = 1)'
6197
6198    Args:
6199        *expressions: the SQL code strings to parse.
6200            If an Expression instance is passed, this is used as-is.
6201        dialect: the dialect used to parse the input expression.
6202        copy: whether or not to copy `expressions` (only applies to Expressions).
6203        **opts: other options to use to parse the input expressions.
6204
6205    Returns:
6206        And: the new condition
6207    """
6208    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:
6211def or_(
6212    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6213) -> Condition:
6214    """
6215    Combine multiple conditions with an OR logical operator.
6216
6217    Example:
6218        >>> or_("x=1", or_("y=1", "z=1")).sql()
6219        'x = 1 OR (y = 1 OR z = 1)'
6220
6221    Args:
6222        *expressions: the SQL code strings to parse.
6223            If an Expression instance is passed, this is used as-is.
6224        dialect: the dialect used to parse the input expression.
6225        copy: whether or not to copy `expressions` (only applies to Expressions).
6226        **opts: other options to use to parse the input expressions.
6227
6228    Returns:
6229        Or: the new condition
6230    """
6231    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:
6234def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6235    """
6236    Wrap a condition with a NOT operator.
6237
6238    Example:
6239        >>> not_("this_suit='black'").sql()
6240        "NOT this_suit = 'black'"
6241
6242    Args:
6243        expression: the SQL code string to parse.
6244            If an Expression instance is passed, this is used as-is.
6245        dialect: the dialect used to parse the input expression.
6246        copy: whether to copy the expression or not.
6247        **opts: other options to use to parse the input expressions.
6248
6249    Returns:
6250        The new condition.
6251    """
6252    this = condition(
6253        expression,
6254        dialect=dialect,
6255        copy=copy,
6256        **opts,
6257    )
6258    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:
6261def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6262    """
6263    Wrap an expression in parentheses.
6264
6265    Example:
6266        >>> paren("5 + 3").sql()
6267        '(5 + 3)'
6268
6269    Args:
6270        expression: the SQL code string to parse.
6271            If an Expression instance is passed, this is used as-is.
6272        copy: whether to copy the expression or not.
6273
6274    Returns:
6275        The wrapped expression.
6276    """
6277    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):
6295def to_identifier(name, quoted=None, copy=True):
6296    """Builds an identifier.
6297
6298    Args:
6299        name: The name to turn into an identifier.
6300        quoted: Whether or not force quote the identifier.
6301        copy: Whether or not to copy name if it's an Identifier.
6302
6303    Returns:
6304        The identifier ast node.
6305    """
6306
6307    if name is None:
6308        return None
6309
6310    if isinstance(name, Identifier):
6311        identifier = maybe_copy(name, copy)
6312    elif isinstance(name, str):
6313        identifier = Identifier(
6314            this=name,
6315            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6316        )
6317    else:
6318        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6319    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:
6322def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6323    """
6324    Parses a given string into an identifier.
6325
6326    Args:
6327        name: The name to parse into an identifier.
6328        dialect: The dialect to parse against.
6329
6330    Returns:
6331        The identifier ast node.
6332    """
6333    try:
6334        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6335    except ParseError:
6336        expression = to_identifier(name)
6337
6338    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:
6344def to_interval(interval: str | Literal) -> Interval:
6345    """Builds an interval expression from a string like '1 day' or '5 months'."""
6346    if isinstance(interval, Literal):
6347        if not interval.is_string:
6348            raise ValueError("Invalid interval string.")
6349
6350        interval = interval.this
6351
6352    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6353
6354    if not interval_parts:
6355        raise ValueError("Invalid interval string.")
6356
6357    return Interval(
6358        this=Literal.string(interval_parts.group(1)),
6359        unit=Var(this=interval_parts.group(2).upper()),
6360    )

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

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

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

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:
6696def rename_column(
6697    table_name: str | Table,
6698    old_column_name: str | Column,
6699    new_column_name: str | Column,
6700    exists: t.Optional[bool] = None,
6701) -> AlterTable:
6702    """Build ALTER TABLE... RENAME COLUMN... expression
6703
6704    Args:
6705        table_name: Name of the table
6706        old_column: The old name of the column
6707        new_column: The new name of the column
6708        exists: Whether or not to add the `IF EXISTS` clause
6709
6710    Returns:
6711        Alter table expression
6712    """
6713    table = to_table(table_name)
6714    old_column = to_column(old_column_name)
6715    new_column = to_column(new_column_name)
6716    return AlterTable(
6717        this=table,
6718        actions=[
6719            RenameColumn(this=old_column, to=new_column, exists=exists),
6720        ],
6721    )

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

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

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:
6845def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6846    """Returns a case normalized table name without quotes.
6847
6848    Args:
6849        table: the table to normalize
6850        dialect: the dialect to use for normalization rules
6851        copy: whether or not to copy the expression.
6852
6853    Examples:
6854        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6855        'A-B.c'
6856    """
6857    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6858
6859    return ".".join(
6860        p.name
6861        for p in normalize_identifiers(
6862            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6863        ).parts
6864    )

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

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether or not to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
7114def tuple_(
7115    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7116) -> Tuple:
7117    """
7118    Returns an tuple.
7119
7120    Examples:
7121        >>> tuple_(1, 'x').sql()
7122        '(1, x)'
7123
7124    Args:
7125        expressions: the expressions to add to the tuple.
7126        copy: whether or not to copy the argument expressions.
7127        dialect: the source dialect.
7128        kwargs: the kwargs used to instantiate the function of interest.
7129
7130    Returns:
7131        A tuple expression.
7132    """
7133    return Tuple(
7134        expressions=[
7135            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7136            for expression in expressions
7137        ]
7138    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether or not to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

A tuple expression.

def true() -> Boolean:
7141def true() -> Boolean:
7142    """
7143    Returns a true Boolean expression.
7144    """
7145    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7148def false() -> Boolean:
7149    """
7150    Returns a false Boolean expression.
7151    """
7152    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7155def null() -> Null:
7156    """
7157    Returns a Null expression.
7158    """
7159    return Null()

Returns a Null expression.