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

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 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:
6190def and_(
6191    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6192) -> Condition:
6193    """
6194    Combine multiple conditions with an AND logical operator.
6195
6196    Example:
6197        >>> and_("x=1", and_("y=1", "z=1")).sql()
6198        'x = 1 AND (y = 1 AND z = 1)'
6199
6200    Args:
6201        *expressions: the SQL code strings to parse.
6202            If an Expression instance is passed, this is used as-is.
6203        dialect: the dialect used to parse the input expression.
6204        copy: whether to copy `expressions` (only applies to Expressions).
6205        **opts: other options to use to parse the input expressions.
6206
6207    Returns:
6208        And: the new condition
6209    """
6210    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 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:
6213def or_(
6214    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6215) -> Condition:
6216    """
6217    Combine multiple conditions with an OR logical operator.
6218
6219    Example:
6220        >>> or_("x=1", or_("y=1", "z=1")).sql()
6221        'x = 1 OR (y = 1 OR z = 1)'
6222
6223    Args:
6224        *expressions: the SQL code strings to parse.
6225            If an Expression instance is passed, this is used as-is.
6226        dialect: the dialect used to parse the input expression.
6227        copy: whether to copy `expressions` (only applies to Expressions).
6228        **opts: other options to use to parse the input expressions.
6229
6230    Returns:
6231        Or: the new condition
6232    """
6233    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 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:
6236def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6237    """
6238    Wrap a condition with a NOT operator.
6239
6240    Example:
6241        >>> not_("this_suit='black'").sql()
6242        "NOT this_suit = 'black'"
6243
6244    Args:
6245        expression: the SQL code string to parse.
6246            If an Expression instance is passed, this is used as-is.
6247        dialect: the dialect used to parse the input expression.
6248        copy: whether to copy the expression or not.
6249        **opts: other options to use to parse the input expressions.
6250
6251    Returns:
6252        The new condition.
6253    """
6254    this = condition(
6255        expression,
6256        dialect=dialect,
6257        copy=copy,
6258        **opts,
6259    )
6260    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:
6263def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6264    """
6265    Wrap an expression in parentheses.
6266
6267    Example:
6268        >>> paren("5 + 3").sql()
6269        '(5 + 3)'
6270
6271    Args:
6272        expression: the SQL code string to parse.
6273            If an Expression instance is passed, this is used as-is.
6274        copy: whether to copy the expression or not.
6275
6276    Returns:
6277        The wrapped expression.
6278    """
6279    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):
6297def to_identifier(name, quoted=None, copy=True):
6298    """Builds an identifier.
6299
6300    Args:
6301        name: The name to turn into an identifier.
6302        quoted: Whether to force quote the identifier.
6303        copy: Whether to copy name if it's an Identifier.
6304
6305    Returns:
6306        The identifier ast node.
6307    """
6308
6309    if name is None:
6310        return None
6311
6312    if isinstance(name, Identifier):
6313        identifier = maybe_copy(name, copy)
6314    elif isinstance(name, str):
6315        identifier = Identifier(
6316            this=name,
6317            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6318        )
6319    else:
6320        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6321    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether 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:
6324def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6325    """
6326    Parses a given string into an identifier.
6327
6328    Args:
6329        name: The name to parse into an identifier.
6330        dialect: The dialect to parse against.
6331
6332    Returns:
6333        The identifier ast node.
6334    """
6335    try:
6336        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6337    except ParseError:
6338        expression = to_identifier(name)
6339
6340    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:
6346def to_interval(interval: str | Literal) -> Interval:
6347    """Builds an interval expression from a string like '1 day' or '5 months'."""
6348    if isinstance(interval, Literal):
6349        if not interval.is_string:
6350            raise ValueError("Invalid interval string.")
6351
6352        interval = interval.this
6353
6354    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6355
6356    if not interval_parts:
6357        raise ValueError("Invalid interval string.")
6358
6359    return Interval(
6360        this=Literal.string(interval_parts.group(1)),
6361        unit=Var(this=interval_parts.group(2).upper()),
6362    )

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]:
6375def to_table(
6376    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6377) -> t.Optional[Table]:
6378    """
6379    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6380    If a table is passed in then that table is returned.
6381
6382    Args:
6383        sql_path: a `[catalog].[schema].[table]` string.
6384        dialect: the source dialect according to which the table name will be parsed.
6385        copy: Whether to copy a table if it is passed in.
6386        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6387
6388    Returns:
6389        A table expression.
6390    """
6391    if sql_path is None or isinstance(sql_path, Table):
6392        return maybe_copy(sql_path, copy=copy)
6393    if not isinstance(sql_path, str):
6394        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6395
6396    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6397    if table:
6398        for k, v in kwargs.items():
6399            table.set(k, v)
6400
6401    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 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:
6404def to_column(sql_path: str | Column, **kwargs) -> Column:
6405    """
6406    Create a column from a `[table].[column]` sql path. Schema is optional.
6407
6408    If a column is passed in then that column is returned.
6409
6410    Args:
6411        sql_path: `[table].[column]` string
6412    Returns:
6413        Table: A column expression
6414    """
6415    if sql_path is None or isinstance(sql_path, Column):
6416        return sql_path
6417    if not isinstance(sql_path, str):
6418        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6419    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: Union[Identifier, str, NoneType], 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):
6422def alias_(
6423    expression: ExpOrStr,
6424    alias: t.Optional[str | Identifier],
6425    table: bool | t.Sequence[str | Identifier] = False,
6426    quoted: t.Optional[bool] = None,
6427    dialect: DialectType = None,
6428    copy: bool = True,
6429    **opts,
6430):
6431    """Create an Alias expression.
6432
6433    Example:
6434        >>> alias_('foo', 'bar').sql()
6435        'foo AS bar'
6436
6437        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6438        '(SELECT 1, 2) AS bar(a, b)'
6439
6440    Args:
6441        expression: the SQL code strings to parse.
6442            If an Expression instance is passed, this is used as-is.
6443        alias: the alias name to use. If the name has
6444            special characters it is quoted.
6445        table: Whether to create a table alias, can also be a list of columns.
6446        quoted: whether to quote the alias
6447        dialect: the dialect used to parse the input expression.
6448        copy: Whether to copy the expression.
6449        **opts: other options to use to parse the input expressions.
6450
6451    Returns:
6452        Alias: the aliased expression
6453    """
6454    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6455    alias = to_identifier(alias, quoted=quoted)
6456
6457    if table:
6458        table_alias = TableAlias(this=alias)
6459        exp.set("alias", table_alias)
6460
6461        if not isinstance(table, bool):
6462            for column in table:
6463                table_alias.append("columns", to_identifier(column, quoted=quoted))
6464
6465        return exp
6466
6467    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6468    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6469    # for the complete Window expression.
6470    #
6471    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6472
6473    if "alias" in exp.arg_types and not isinstance(exp, Window):
6474        exp.set("alias", alias)
6475        return exp
6476    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 to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

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:
6479def subquery(
6480    expression: ExpOrStr,
6481    alias: t.Optional[Identifier | str] = None,
6482    dialect: DialectType = None,
6483    **opts,
6484) -> Select:
6485    """
6486    Build a subquery expression.
6487
6488    Example:
6489        >>> subquery('select x from tbl', 'bar').select('x').sql()
6490        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6491
6492    Args:
6493        expression: the SQL code strings to parse.
6494            If an Expression instance is passed, this is used as-is.
6495        alias: the alias name to use.
6496        dialect: the dialect used to parse the input expression.
6497        **opts: other options to use to parse the input expressions.
6498
6499    Returns:
6500        A new Select instance with the subquery expression included.
6501    """
6502
6503    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6504    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):
6535def column(
6536    col,
6537    table=None,
6538    db=None,
6539    catalog=None,
6540    *,
6541    fields=None,
6542    quoted=None,
6543    copy=True,
6544):
6545    """
6546    Build a Column.
6547
6548    Args:
6549        col: Column name.
6550        table: Table name.
6551        db: Database name.
6552        catalog: Catalog name.
6553        fields: Additional fields using dots.
6554        quoted: Whether to force quotes on the column's identifiers.
6555        copy: Whether to copy identifiers if passed in.
6556
6557    Returns:
6558        The new Column instance.
6559    """
6560    this = Column(
6561        this=to_identifier(col, quoted=quoted, copy=copy),
6562        table=to_identifier(table, quoted=quoted, copy=copy),
6563        db=to_identifier(db, quoted=quoted, copy=copy),
6564        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6565    )
6566
6567    if fields:
6568        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6569    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 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:
6572def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6573    """Cast an expression to a data type.
6574
6575    Example:
6576        >>> cast('x + 1', 'int').sql()
6577        'CAST(x + 1 AS INT)'
6578
6579    Args:
6580        expression: The expression to cast.
6581        to: The datatype to cast to.
6582        copy: Whether to copy the supplied expressions.
6583
6584    Returns:
6585        The new Cast instance.
6586    """
6587    expression = maybe_parse(expression, copy=copy, **opts)
6588    data_type = DataType.build(to, copy=copy, **opts)
6589    expression = Cast(this=expression, to=data_type)
6590    expression.type = data_type
6591    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 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:
6594def table_(
6595    table: Identifier | str,
6596    db: t.Optional[Identifier | str] = None,
6597    catalog: t.Optional[Identifier | str] = None,
6598    quoted: t.Optional[bool] = None,
6599    alias: t.Optional[Identifier | str] = None,
6600) -> Table:
6601    """Build a Table.
6602
6603    Args:
6604        table: Table name.
6605        db: Database name.
6606        catalog: Catalog name.
6607        quote: Whether to force quotes on the table's identifiers.
6608        alias: Table's alias.
6609
6610    Returns:
6611        The new Table instance.
6612    """
6613    return Table(
6614        this=to_identifier(table, quoted=quoted) if table else None,
6615        db=to_identifier(db, quoted=quoted) if db else None,
6616        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6617        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6618    )

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

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

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

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 to add the IF EXISTS clause
Returns:

Alter table expression

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

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

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

Returns a case normalized table name without quotes.

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

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether 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:
7117def tuple_(
7118    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7119) -> Tuple:
7120    """
7121    Returns an tuple.
7122
7123    Examples:
7124        >>> tuple_(1, 'x').sql()
7125        '(1, x)'
7126
7127    Args:
7128        expressions: the expressions to add to the tuple.
7129        copy: whether to copy the argument expressions.
7130        dialect: the source dialect.
7131        kwargs: the kwargs used to instantiate the function of interest.
7132
7133    Returns:
7134        A tuple expression.
7135    """
7136    return Tuple(
7137        expressions=[
7138            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7139            for expression in expressions
7140        ]
7141    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether 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:
7144def true() -> Boolean:
7145    """
7146    Returns a true Boolean expression.
7147    """
7148    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7151def false() -> Boolean:
7152    """
7153    Returns a false Boolean expression.
7154    """
7155    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7158def null() -> Null:
7159    """
7160    Returns a Null expression.
7161    """
7162    return Null()

Returns a Null expression.