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    arg_types = {"this": True, "enforced": False}
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 = {"expressions": True}
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 AddMonths(Func):
5201    arg_types = {"this": True, "expression": True}
5202
5203
5204class Nvl2(Func):
5205    arg_types = {"this": True, "true": True, "false": False}
5206
5207
5208# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5209class Predict(Func):
5210    arg_types = {"this": True, "expression": True, "params_struct": False}
5211
5212
5213class Pow(Binary, Func):
5214    _sql_names = ["POWER", "POW"]
5215
5216
5217class PercentileCont(AggFunc):
5218    arg_types = {"this": True, "expression": False}
5219
5220
5221class PercentileDisc(AggFunc):
5222    arg_types = {"this": True, "expression": False}
5223
5224
5225class Quantile(AggFunc):
5226    arg_types = {"this": True, "quantile": True}
5227
5228
5229class ApproxQuantile(Quantile):
5230    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5231
5232
5233class Rand(Func):
5234    _sql_names = ["RAND", "RANDOM"]
5235    arg_types = {"this": False}
5236
5237
5238class Randn(Func):
5239    arg_types = {"this": False}
5240
5241
5242class RangeN(Func):
5243    arg_types = {"this": True, "expressions": True, "each": False}
5244
5245
5246class ReadCSV(Func):
5247    _sql_names = ["READ_CSV"]
5248    is_var_len_args = True
5249    arg_types = {"this": True, "expressions": False}
5250
5251
5252class Reduce(Func):
5253    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5254
5255
5256class RegexpExtract(Func):
5257    arg_types = {
5258        "this": True,
5259        "expression": True,
5260        "position": False,
5261        "occurrence": False,
5262        "parameters": False,
5263        "group": False,
5264    }
5265
5266
5267class RegexpReplace(Func):
5268    arg_types = {
5269        "this": True,
5270        "expression": True,
5271        "replacement": False,
5272        "position": False,
5273        "occurrence": False,
5274        "parameters": False,
5275        "modifiers": False,
5276    }
5277
5278
5279class RegexpLike(Binary, Func):
5280    arg_types = {"this": True, "expression": True, "flag": False}
5281
5282
5283class RegexpILike(Binary, Func):
5284    arg_types = {"this": True, "expression": True, "flag": False}
5285
5286
5287# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5288# limit is the number of times a pattern is applied
5289class RegexpSplit(Func):
5290    arg_types = {"this": True, "expression": True, "limit": False}
5291
5292
5293class Repeat(Func):
5294    arg_types = {"this": True, "times": True}
5295
5296
5297# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
5298# tsql third argument function == trunctaion if not 0
5299class Round(Func):
5300    arg_types = {"this": True, "decimals": False, "truncate": False}
5301
5302
5303class RowNumber(Func):
5304    arg_types: t.Dict[str, t.Any] = {}
5305
5306
5307class SafeDivide(Func):
5308    arg_types = {"this": True, "expression": True}
5309
5310
5311class SHA(Func):
5312    _sql_names = ["SHA", "SHA1"]
5313
5314
5315class SHA2(Func):
5316    _sql_names = ["SHA2"]
5317    arg_types = {"this": True, "length": False}
5318
5319
5320class Sign(Func):
5321    _sql_names = ["SIGN", "SIGNUM"]
5322
5323
5324class SortArray(Func):
5325    arg_types = {"this": True, "asc": False}
5326
5327
5328class Split(Func):
5329    arg_types = {"this": True, "expression": True, "limit": False}
5330
5331
5332# Start may be omitted in the case of postgres
5333# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5334class Substring(Func):
5335    arg_types = {"this": True, "start": False, "length": False}
5336
5337
5338class StandardHash(Func):
5339    arg_types = {"this": True, "expression": False}
5340
5341
5342class StartsWith(Func):
5343    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5344    arg_types = {"this": True, "expression": True}
5345
5346
5347class StrPosition(Func):
5348    arg_types = {
5349        "this": True,
5350        "substr": True,
5351        "position": False,
5352        "instance": False,
5353    }
5354
5355
5356class StrToDate(Func):
5357    arg_types = {"this": True, "format": True}
5358
5359
5360class StrToTime(Func):
5361    arg_types = {"this": True, "format": True, "zone": False}
5362
5363
5364# Spark allows unix_timestamp()
5365# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5366class StrToUnix(Func):
5367    arg_types = {"this": False, "format": False}
5368
5369
5370# https://prestodb.io/docs/current/functions/string.html
5371# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5372class StrToMap(Func):
5373    arg_types = {
5374        "this": True,
5375        "pair_delim": False,
5376        "key_value_delim": False,
5377        "duplicate_resolution_callback": False,
5378    }
5379
5380
5381class NumberToStr(Func):
5382    arg_types = {"this": True, "format": True, "culture": False}
5383
5384
5385class FromBase(Func):
5386    arg_types = {"this": True, "expression": True}
5387
5388
5389class Struct(Func):
5390    arg_types = {"expressions": False}
5391    is_var_len_args = True
5392
5393
5394class StructExtract(Func):
5395    arg_types = {"this": True, "expression": True}
5396
5397
5398# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5399# https://docs.snowflake.com/en/sql-reference/functions/insert
5400class Stuff(Func):
5401    _sql_names = ["STUFF", "INSERT"]
5402    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5403
5404
5405class Sum(AggFunc):
5406    pass
5407
5408
5409class Sqrt(Func):
5410    pass
5411
5412
5413class Stddev(AggFunc):
5414    pass
5415
5416
5417class StddevPop(AggFunc):
5418    pass
5419
5420
5421class StddevSamp(AggFunc):
5422    pass
5423
5424
5425class TimeToStr(Func):
5426    arg_types = {"this": True, "format": True, "culture": False}
5427
5428
5429class TimeToTimeStr(Func):
5430    pass
5431
5432
5433class TimeToUnix(Func):
5434    pass
5435
5436
5437class TimeStrToDate(Func):
5438    pass
5439
5440
5441class TimeStrToTime(Func):
5442    pass
5443
5444
5445class TimeStrToUnix(Func):
5446    pass
5447
5448
5449class Trim(Func):
5450    arg_types = {
5451        "this": True,
5452        "expression": False,
5453        "position": False,
5454        "collation": False,
5455    }
5456
5457
5458class TsOrDsAdd(Func, TimeUnit):
5459    # return_type is used to correctly cast the arguments of this expression when transpiling it
5460    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5461
5462    @property
5463    def return_type(self) -> DataType:
5464        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5465
5466
5467class TsOrDsDiff(Func, TimeUnit):
5468    arg_types = {"this": True, "expression": True, "unit": False}
5469
5470
5471class TsOrDsToDateStr(Func):
5472    pass
5473
5474
5475class TsOrDsToDate(Func):
5476    arg_types = {"this": True, "format": False}
5477
5478
5479class TsOrDsToTime(Func):
5480    pass
5481
5482
5483class TsOrDiToDi(Func):
5484    pass
5485
5486
5487class Unhex(Func):
5488    pass
5489
5490
5491# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
5492class UnixDate(Func):
5493    pass
5494
5495
5496class UnixToStr(Func):
5497    arg_types = {"this": True, "format": False}
5498
5499
5500# https://prestodb.io/docs/current/functions/datetime.html
5501# presto has weird zone/hours/minutes
5502class UnixToTime(Func):
5503    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5504
5505    SECONDS = Literal.number(0)
5506    DECIS = Literal.number(1)
5507    CENTIS = Literal.number(2)
5508    MILLIS = Literal.number(3)
5509    DECIMILLIS = Literal.number(4)
5510    CENTIMILLIS = Literal.number(5)
5511    MICROS = Literal.number(6)
5512    DECIMICROS = Literal.number(7)
5513    CENTIMICROS = Literal.number(8)
5514    NANOS = Literal.number(9)
5515
5516
5517class UnixToTimeStr(Func):
5518    pass
5519
5520
5521class TimestampFromParts(Func):
5522    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5523    arg_types = {
5524        "year": True,
5525        "month": True,
5526        "day": True,
5527        "hour": True,
5528        "min": True,
5529        "sec": True,
5530        "nano": False,
5531        "zone": False,
5532        "milli": False,
5533    }
5534
5535
5536class Upper(Func):
5537    _sql_names = ["UPPER", "UCASE"]
5538
5539
5540class Variance(AggFunc):
5541    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5542
5543
5544class VariancePop(AggFunc):
5545    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5546
5547
5548class Week(Func):
5549    arg_types = {"this": True, "mode": False}
5550
5551
5552class XMLTable(Func):
5553    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5554
5555
5556class Year(Func):
5557    pass
5558
5559
5560class Use(Expression):
5561    arg_types = {"this": True, "kind": False}
5562
5563
5564class Merge(Expression):
5565    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
5566
5567
5568class When(Func):
5569    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5570
5571
5572# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5573# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5574class NextValueFor(Func):
5575    arg_types = {"this": True, "order": False}
5576
5577
5578def _norm_arg(arg):
5579    return arg.lower() if type(arg) is str else arg
5580
5581
5582ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5583FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
5584
5585JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
5586
5587
5588# Helpers
5589@t.overload
5590def maybe_parse(
5591    sql_or_expression: ExpOrStr,
5592    *,
5593    into: t.Type[E],
5594    dialect: DialectType = None,
5595    prefix: t.Optional[str] = None,
5596    copy: bool = False,
5597    **opts,
5598) -> E:
5599    ...
5600
5601
5602@t.overload
5603def maybe_parse(
5604    sql_or_expression: str | E,
5605    *,
5606    into: t.Optional[IntoType] = None,
5607    dialect: DialectType = None,
5608    prefix: t.Optional[str] = None,
5609    copy: bool = False,
5610    **opts,
5611) -> E:
5612    ...
5613
5614
5615def maybe_parse(
5616    sql_or_expression: ExpOrStr,
5617    *,
5618    into: t.Optional[IntoType] = None,
5619    dialect: DialectType = None,
5620    prefix: t.Optional[str] = None,
5621    copy: bool = False,
5622    **opts,
5623) -> Expression:
5624    """Gracefully handle a possible string or expression.
5625
5626    Example:
5627        >>> maybe_parse("1")
5628        Literal(this=1, is_string=False)
5629        >>> maybe_parse(to_identifier("x"))
5630        Identifier(this=x, quoted=False)
5631
5632    Args:
5633        sql_or_expression: the SQL code string or an expression
5634        into: the SQLGlot Expression to parse into
5635        dialect: the dialect used to parse the input expressions (in the case that an
5636            input expression is a SQL string).
5637        prefix: a string to prefix the sql with before it gets parsed
5638            (automatically includes a space)
5639        copy: whether to copy the expression.
5640        **opts: other options to use to parse the input expressions (again, in the case
5641            that an input expression is a SQL string).
5642
5643    Returns:
5644        Expression: the parsed or given expression.
5645    """
5646    if isinstance(sql_or_expression, Expression):
5647        if copy:
5648            return sql_or_expression.copy()
5649        return sql_or_expression
5650
5651    if sql_or_expression is None:
5652        raise ParseError("SQL cannot be None")
5653
5654    import sqlglot
5655
5656    sql = str(sql_or_expression)
5657    if prefix:
5658        sql = f"{prefix} {sql}"
5659
5660    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5661
5662
5663@t.overload
5664def maybe_copy(instance: None, copy: bool = True) -> None:
5665    ...
5666
5667
5668@t.overload
5669def maybe_copy(instance: E, copy: bool = True) -> E:
5670    ...
5671
5672
5673def maybe_copy(instance, copy=True):
5674    return instance.copy() if copy and instance else instance
5675
5676
5677def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
5678    """Generate a textual representation of an Expression tree"""
5679    indent = "\n" + ("  " * (level + 1))
5680    delim = f",{indent}"
5681
5682    if isinstance(node, Expression):
5683        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
5684
5685        if (node.type or verbose) and not isinstance(node, DataType):
5686            args["_type"] = node.type
5687        if node.comments or verbose:
5688            args["_comments"] = node.comments
5689
5690        if verbose:
5691            args["_id"] = id(node)
5692
5693        # Inline leaves for a more compact representation
5694        if node.is_leaf():
5695            indent = ""
5696            delim = ", "
5697
5698        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
5699        return f"{node.__class__.__name__}({indent}{items})"
5700
5701    if isinstance(node, list):
5702        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
5703        items = f"{indent}{items}" if items else ""
5704        return f"[{items}]"
5705
5706    # Indent multiline strings to match the current level
5707    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
5708
5709
5710def _is_wrong_expression(expression, into):
5711    return isinstance(expression, Expression) and not isinstance(expression, into)
5712
5713
5714def _apply_builder(
5715    expression,
5716    instance,
5717    arg,
5718    copy=True,
5719    prefix=None,
5720    into=None,
5721    dialect=None,
5722    into_arg="this",
5723    **opts,
5724):
5725    if _is_wrong_expression(expression, into):
5726        expression = into(**{into_arg: expression})
5727    instance = maybe_copy(instance, copy)
5728    expression = maybe_parse(
5729        sql_or_expression=expression,
5730        prefix=prefix,
5731        into=into,
5732        dialect=dialect,
5733        **opts,
5734    )
5735    instance.set(arg, expression)
5736    return instance
5737
5738
5739def _apply_child_list_builder(
5740    *expressions,
5741    instance,
5742    arg,
5743    append=True,
5744    copy=True,
5745    prefix=None,
5746    into=None,
5747    dialect=None,
5748    properties=None,
5749    **opts,
5750):
5751    instance = maybe_copy(instance, copy)
5752    parsed = []
5753    for expression in expressions:
5754        if expression is not None:
5755            if _is_wrong_expression(expression, into):
5756                expression = into(expressions=[expression])
5757
5758            expression = maybe_parse(
5759                expression,
5760                into=into,
5761                dialect=dialect,
5762                prefix=prefix,
5763                **opts,
5764            )
5765            parsed.extend(expression.expressions)
5766
5767    existing = instance.args.get(arg)
5768    if append and existing:
5769        parsed = existing.expressions + parsed
5770
5771    child = into(expressions=parsed)
5772    for k, v in (properties or {}).items():
5773        child.set(k, v)
5774    instance.set(arg, child)
5775
5776    return instance
5777
5778
5779def _apply_list_builder(
5780    *expressions,
5781    instance,
5782    arg,
5783    append=True,
5784    copy=True,
5785    prefix=None,
5786    into=None,
5787    dialect=None,
5788    **opts,
5789):
5790    inst = maybe_copy(instance, copy)
5791
5792    expressions = [
5793        maybe_parse(
5794            sql_or_expression=expression,
5795            into=into,
5796            prefix=prefix,
5797            dialect=dialect,
5798            **opts,
5799        )
5800        for expression in expressions
5801        if expression is not None
5802    ]
5803
5804    existing_expressions = inst.args.get(arg)
5805    if append and existing_expressions:
5806        expressions = existing_expressions + expressions
5807
5808    inst.set(arg, expressions)
5809    return inst
5810
5811
5812def _apply_conjunction_builder(
5813    *expressions,
5814    instance,
5815    arg,
5816    into=None,
5817    append=True,
5818    copy=True,
5819    dialect=None,
5820    **opts,
5821):
5822    expressions = [exp for exp in expressions if exp is not None and exp != ""]
5823    if not expressions:
5824        return instance
5825
5826    inst = maybe_copy(instance, copy)
5827
5828    existing = inst.args.get(arg)
5829    if append and existing is not None:
5830        expressions = [existing.this if into else existing] + list(expressions)
5831
5832    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
5833
5834    inst.set(arg, into(this=node) if into else node)
5835    return inst
5836
5837
5838def _apply_cte_builder(
5839    instance: E,
5840    alias: ExpOrStr,
5841    as_: ExpOrStr,
5842    recursive: t.Optional[bool] = None,
5843    append: bool = True,
5844    dialect: DialectType = None,
5845    copy: bool = True,
5846    **opts,
5847) -> E:
5848    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
5849    as_expression = maybe_parse(as_, dialect=dialect, **opts)
5850    cte = CTE(this=as_expression, alias=alias_expression)
5851    return _apply_child_list_builder(
5852        cte,
5853        instance=instance,
5854        arg="with",
5855        append=append,
5856        copy=copy,
5857        into=With,
5858        properties={"recursive": recursive or False},
5859    )
5860
5861
5862def _combine(
5863    expressions: t.Sequence[t.Optional[ExpOrStr]],
5864    operator: t.Type[Connector],
5865    dialect: DialectType = None,
5866    copy: bool = True,
5867    **opts,
5868) -> Expression:
5869    conditions = [
5870        condition(expression, dialect=dialect, copy=copy, **opts)
5871        for expression in expressions
5872        if expression is not None
5873    ]
5874
5875    this, *rest = conditions
5876    if rest:
5877        this = _wrap(this, Connector)
5878    for expression in rest:
5879        this = operator(this=this, expression=_wrap(expression, Connector))
5880
5881    return this
5882
5883
5884def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
5885    return Paren(this=expression) if isinstance(expression, kind) else expression
5886
5887
5888def union(
5889    left: ExpOrStr,
5890    right: ExpOrStr,
5891    distinct: bool = True,
5892    dialect: DialectType = None,
5893    copy: bool = True,
5894    **opts,
5895) -> Union:
5896    """
5897    Initializes a syntax tree from one UNION expression.
5898
5899    Example:
5900        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5901        'SELECT * FROM foo UNION SELECT * FROM bla'
5902
5903    Args:
5904        left: the SQL code string corresponding to the left-hand side.
5905            If an `Expression` instance is passed, it will be used as-is.
5906        right: the SQL code string corresponding to the right-hand side.
5907            If an `Expression` instance is passed, it will be used as-is.
5908        distinct: set the DISTINCT flag if and only if this is true.
5909        dialect: the dialect used to parse the input expression.
5910        copy: whether to copy the expression.
5911        opts: other options to use to parse the input expressions.
5912
5913    Returns:
5914        The new Union instance.
5915    """
5916    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5917    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5918
5919    return Union(this=left, expression=right, distinct=distinct)
5920
5921
5922def intersect(
5923    left: ExpOrStr,
5924    right: ExpOrStr,
5925    distinct: bool = True,
5926    dialect: DialectType = None,
5927    copy: bool = True,
5928    **opts,
5929) -> Intersect:
5930    """
5931    Initializes a syntax tree from one INTERSECT expression.
5932
5933    Example:
5934        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5935        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5936
5937    Args:
5938        left: the SQL code string corresponding to the left-hand side.
5939            If an `Expression` instance is passed, it will be used as-is.
5940        right: the SQL code string corresponding to the right-hand side.
5941            If an `Expression` instance is passed, it will be used as-is.
5942        distinct: set the DISTINCT flag if and only if this is true.
5943        dialect: the dialect used to parse the input expression.
5944        copy: whether to copy the expression.
5945        opts: other options to use to parse the input expressions.
5946
5947    Returns:
5948        The new Intersect instance.
5949    """
5950    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5951    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5952
5953    return Intersect(this=left, expression=right, distinct=distinct)
5954
5955
5956def except_(
5957    left: ExpOrStr,
5958    right: ExpOrStr,
5959    distinct: bool = True,
5960    dialect: DialectType = None,
5961    copy: bool = True,
5962    **opts,
5963) -> Except:
5964    """
5965    Initializes a syntax tree from one EXCEPT expression.
5966
5967    Example:
5968        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5969        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5970
5971    Args:
5972        left: the SQL code string corresponding to the left-hand side.
5973            If an `Expression` instance is passed, it will be used as-is.
5974        right: the SQL code string corresponding to the right-hand side.
5975            If an `Expression` instance is passed, it will be used as-is.
5976        distinct: set the DISTINCT flag if and only if this is true.
5977        dialect: the dialect used to parse the input expression.
5978        copy: whether to copy the expression.
5979        opts: other options to use to parse the input expressions.
5980
5981    Returns:
5982        The new Except instance.
5983    """
5984    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5985    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5986
5987    return Except(this=left, expression=right, distinct=distinct)
5988
5989
5990def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5991    """
5992    Initializes a syntax tree from one or multiple SELECT expressions.
5993
5994    Example:
5995        >>> select("col1", "col2").from_("tbl").sql()
5996        'SELECT col1, col2 FROM tbl'
5997
5998    Args:
5999        *expressions: the SQL code string to parse as the expressions of a
6000            SELECT statement. If an Expression instance is passed, this is used as-is.
6001        dialect: the dialect used to parse the input expressions (in the case that an
6002            input expression is a SQL string).
6003        **opts: other options to use to parse the input expressions (again, in the case
6004            that an input expression is a SQL string).
6005
6006    Returns:
6007        Select: the syntax tree for the SELECT statement.
6008    """
6009    return Select().select(*expressions, dialect=dialect, **opts)
6010
6011
6012def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6013    """
6014    Initializes a syntax tree from a FROM expression.
6015
6016    Example:
6017        >>> from_("tbl").select("col1", "col2").sql()
6018        'SELECT col1, col2 FROM tbl'
6019
6020    Args:
6021        *expression: the SQL code string to parse as the FROM expressions of a
6022            SELECT statement. If an Expression instance is passed, this is used as-is.
6023        dialect: the dialect used to parse the input expression (in the case that the
6024            input expression is a SQL string).
6025        **opts: other options to use to parse the input expressions (again, in the case
6026            that the input expression is a SQL string).
6027
6028    Returns:
6029        Select: the syntax tree for the SELECT statement.
6030    """
6031    return Select().from_(expression, dialect=dialect, **opts)
6032
6033
6034def update(
6035    table: str | Table,
6036    properties: dict,
6037    where: t.Optional[ExpOrStr] = None,
6038    from_: t.Optional[ExpOrStr] = None,
6039    dialect: DialectType = None,
6040    **opts,
6041) -> Update:
6042    """
6043    Creates an update statement.
6044
6045    Example:
6046        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6047        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6048
6049    Args:
6050        *properties: dictionary of properties to set which are
6051            auto converted to sql objects eg None -> NULL
6052        where: sql conditional parsed into a WHERE statement
6053        from_: sql statement parsed into a FROM statement
6054        dialect: the dialect used to parse the input expressions.
6055        **opts: other options to use to parse the input expressions.
6056
6057    Returns:
6058        Update: the syntax tree for the UPDATE statement.
6059    """
6060    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6061    update_expr.set(
6062        "expressions",
6063        [
6064            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6065            for k, v in properties.items()
6066        ],
6067    )
6068    if from_:
6069        update_expr.set(
6070            "from",
6071            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6072        )
6073    if isinstance(where, Condition):
6074        where = Where(this=where)
6075    if where:
6076        update_expr.set(
6077            "where",
6078            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6079        )
6080    return update_expr
6081
6082
6083def delete(
6084    table: ExpOrStr,
6085    where: t.Optional[ExpOrStr] = None,
6086    returning: t.Optional[ExpOrStr] = None,
6087    dialect: DialectType = None,
6088    **opts,
6089) -> Delete:
6090    """
6091    Builds a delete statement.
6092
6093    Example:
6094        >>> delete("my_table", where="id > 1").sql()
6095        'DELETE FROM my_table WHERE id > 1'
6096
6097    Args:
6098        where: sql conditional parsed into a WHERE statement
6099        returning: sql conditional parsed into a RETURNING statement
6100        dialect: the dialect used to parse the input expressions.
6101        **opts: other options to use to parse the input expressions.
6102
6103    Returns:
6104        Delete: the syntax tree for the DELETE statement.
6105    """
6106    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6107    if where:
6108        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6109    if returning:
6110        delete_expr = t.cast(
6111            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6112        )
6113    return delete_expr
6114
6115
6116def insert(
6117    expression: ExpOrStr,
6118    into: ExpOrStr,
6119    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6120    overwrite: t.Optional[bool] = None,
6121    returning: t.Optional[ExpOrStr] = None,
6122    dialect: DialectType = None,
6123    copy: bool = True,
6124    **opts,
6125) -> Insert:
6126    """
6127    Builds an INSERT statement.
6128
6129    Example:
6130        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6131        'INSERT INTO tbl VALUES (1, 2, 3)'
6132
6133    Args:
6134        expression: the sql string or expression of the INSERT statement
6135        into: the tbl to insert data to.
6136        columns: optionally the table's column names.
6137        overwrite: whether to INSERT OVERWRITE or not.
6138        returning: sql conditional parsed into a RETURNING statement
6139        dialect: the dialect used to parse the input expressions.
6140        copy: whether to copy the expression.
6141        **opts: other options to use to parse the input expressions.
6142
6143    Returns:
6144        Insert: the syntax tree for the INSERT statement.
6145    """
6146    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6147    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6148
6149    if columns:
6150        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6151
6152    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6153
6154    if returning:
6155        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6156
6157    return insert
6158
6159
6160def condition(
6161    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6162) -> Condition:
6163    """
6164    Initialize a logical condition expression.
6165
6166    Example:
6167        >>> condition("x=1").sql()
6168        'x = 1'
6169
6170        This is helpful for composing larger logical syntax trees:
6171        >>> where = condition("x=1")
6172        >>> where = where.and_("y=1")
6173        >>> Select().from_("tbl").select("*").where(where).sql()
6174        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6175
6176    Args:
6177        *expression: the SQL code string to parse.
6178            If an Expression instance is passed, this is used as-is.
6179        dialect: the dialect used to parse the input expression (in the case that the
6180            input expression is a SQL string).
6181        copy: Whether to copy `expression` (only applies to expressions).
6182        **opts: other options to use to parse the input expressions (again, in the case
6183            that the input expression is a SQL string).
6184
6185    Returns:
6186        The new Condition instance
6187    """
6188    return maybe_parse(
6189        expression,
6190        into=Condition,
6191        dialect=dialect,
6192        copy=copy,
6193        **opts,
6194    )
6195
6196
6197def and_(
6198    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6199) -> Condition:
6200    """
6201    Combine multiple conditions with an AND logical operator.
6202
6203    Example:
6204        >>> and_("x=1", and_("y=1", "z=1")).sql()
6205        'x = 1 AND (y = 1 AND z = 1)'
6206
6207    Args:
6208        *expressions: the SQL code strings to parse.
6209            If an Expression instance is passed, this is used as-is.
6210        dialect: the dialect used to parse the input expression.
6211        copy: whether to copy `expressions` (only applies to Expressions).
6212        **opts: other options to use to parse the input expressions.
6213
6214    Returns:
6215        And: the new condition
6216    """
6217    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
6218
6219
6220def or_(
6221    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6222) -> Condition:
6223    """
6224    Combine multiple conditions with an OR logical operator.
6225
6226    Example:
6227        >>> or_("x=1", or_("y=1", "z=1")).sql()
6228        'x = 1 OR (y = 1 OR z = 1)'
6229
6230    Args:
6231        *expressions: the SQL code strings to parse.
6232            If an Expression instance is passed, this is used as-is.
6233        dialect: the dialect used to parse the input expression.
6234        copy: whether to copy `expressions` (only applies to Expressions).
6235        **opts: other options to use to parse the input expressions.
6236
6237    Returns:
6238        Or: the new condition
6239    """
6240    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
6241
6242
6243def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6244    """
6245    Wrap a condition with a NOT operator.
6246
6247    Example:
6248        >>> not_("this_suit='black'").sql()
6249        "NOT this_suit = 'black'"
6250
6251    Args:
6252        expression: the SQL code string to parse.
6253            If an Expression instance is passed, this is used as-is.
6254        dialect: the dialect used to parse the input expression.
6255        copy: whether to copy the expression or not.
6256        **opts: other options to use to parse the input expressions.
6257
6258    Returns:
6259        The new condition.
6260    """
6261    this = condition(
6262        expression,
6263        dialect=dialect,
6264        copy=copy,
6265        **opts,
6266    )
6267    return Not(this=_wrap(this, Connector))
6268
6269
6270def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6271    """
6272    Wrap an expression in parentheses.
6273
6274    Example:
6275        >>> paren("5 + 3").sql()
6276        '(5 + 3)'
6277
6278    Args:
6279        expression: the SQL code string to parse.
6280            If an Expression instance is passed, this is used as-is.
6281        copy: whether to copy the expression or not.
6282
6283    Returns:
6284        The wrapped expression.
6285    """
6286    return Paren(this=maybe_parse(expression, copy=copy))
6287
6288
6289SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
6290
6291
6292@t.overload
6293def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None:
6294    ...
6295
6296
6297@t.overload
6298def to_identifier(
6299    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
6300) -> Identifier:
6301    ...
6302
6303
6304def to_identifier(name, quoted=None, copy=True):
6305    """Builds an identifier.
6306
6307    Args:
6308        name: The name to turn into an identifier.
6309        quoted: Whether to force quote the identifier.
6310        copy: Whether to copy name if it's an Identifier.
6311
6312    Returns:
6313        The identifier ast node.
6314    """
6315
6316    if name is None:
6317        return None
6318
6319    if isinstance(name, Identifier):
6320        identifier = maybe_copy(name, copy)
6321    elif isinstance(name, str):
6322        identifier = Identifier(
6323            this=name,
6324            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6325        )
6326    else:
6327        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6328    return identifier
6329
6330
6331def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6332    """
6333    Parses a given string into an identifier.
6334
6335    Args:
6336        name: The name to parse into an identifier.
6337        dialect: The dialect to parse against.
6338
6339    Returns:
6340        The identifier ast node.
6341    """
6342    try:
6343        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6344    except ParseError:
6345        expression = to_identifier(name)
6346
6347    return expression
6348
6349
6350INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6351
6352
6353def to_interval(interval: str | Literal) -> Interval:
6354    """Builds an interval expression from a string like '1 day' or '5 months'."""
6355    if isinstance(interval, Literal):
6356        if not interval.is_string:
6357            raise ValueError("Invalid interval string.")
6358
6359        interval = interval.this
6360
6361    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6362
6363    if not interval_parts:
6364        raise ValueError("Invalid interval string.")
6365
6366    return Interval(
6367        this=Literal.string(interval_parts.group(1)),
6368        unit=Var(this=interval_parts.group(2).upper()),
6369    )
6370
6371
6372@t.overload
6373def to_table(sql_path: str | Table, **kwargs) -> Table:
6374    ...
6375
6376
6377@t.overload
6378def to_table(sql_path: None, **kwargs) -> None:
6379    ...
6380
6381
6382def to_table(
6383    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6384) -> t.Optional[Table]:
6385    """
6386    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6387    If a table is passed in then that table is returned.
6388
6389    Args:
6390        sql_path: a `[catalog].[schema].[table]` string.
6391        dialect: the source dialect according to which the table name will be parsed.
6392        copy: Whether to copy a table if it is passed in.
6393        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6394
6395    Returns:
6396        A table expression.
6397    """
6398    if sql_path is None or isinstance(sql_path, Table):
6399        return maybe_copy(sql_path, copy=copy)
6400    if not isinstance(sql_path, str):
6401        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6402
6403    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6404    if table:
6405        for k, v in kwargs.items():
6406            table.set(k, v)
6407
6408    return table
6409
6410
6411def to_column(sql_path: str | Column, **kwargs) -> Column:
6412    """
6413    Create a column from a `[table].[column]` sql path. Schema is optional.
6414
6415    If a column is passed in then that column is returned.
6416
6417    Args:
6418        sql_path: `[table].[column]` string
6419    Returns:
6420        Table: A column expression
6421    """
6422    if sql_path is None or isinstance(sql_path, Column):
6423        return sql_path
6424    if not isinstance(sql_path, str):
6425        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6426    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
6427
6428
6429def alias_(
6430    expression: ExpOrStr,
6431    alias: t.Optional[str | Identifier],
6432    table: bool | t.Sequence[str | Identifier] = False,
6433    quoted: t.Optional[bool] = None,
6434    dialect: DialectType = None,
6435    copy: bool = True,
6436    **opts,
6437):
6438    """Create an Alias expression.
6439
6440    Example:
6441        >>> alias_('foo', 'bar').sql()
6442        'foo AS bar'
6443
6444        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6445        '(SELECT 1, 2) AS bar(a, b)'
6446
6447    Args:
6448        expression: the SQL code strings to parse.
6449            If an Expression instance is passed, this is used as-is.
6450        alias: the alias name to use. If the name has
6451            special characters it is quoted.
6452        table: Whether to create a table alias, can also be a list of columns.
6453        quoted: whether to quote the alias
6454        dialect: the dialect used to parse the input expression.
6455        copy: Whether to copy the expression.
6456        **opts: other options to use to parse the input expressions.
6457
6458    Returns:
6459        Alias: the aliased expression
6460    """
6461    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6462    alias = to_identifier(alias, quoted=quoted)
6463
6464    if table:
6465        table_alias = TableAlias(this=alias)
6466        exp.set("alias", table_alias)
6467
6468        if not isinstance(table, bool):
6469            for column in table:
6470                table_alias.append("columns", to_identifier(column, quoted=quoted))
6471
6472        return exp
6473
6474    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6475    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6476    # for the complete Window expression.
6477    #
6478    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6479
6480    if "alias" in exp.arg_types and not isinstance(exp, Window):
6481        exp.set("alias", alias)
6482        return exp
6483    return Alias(this=exp, alias=alias)
6484
6485
6486def subquery(
6487    expression: ExpOrStr,
6488    alias: t.Optional[Identifier | str] = None,
6489    dialect: DialectType = None,
6490    **opts,
6491) -> Select:
6492    """
6493    Build a subquery expression.
6494
6495    Example:
6496        >>> subquery('select x from tbl', 'bar').select('x').sql()
6497        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6498
6499    Args:
6500        expression: the SQL code strings to parse.
6501            If an Expression instance is passed, this is used as-is.
6502        alias: the alias name to use.
6503        dialect: the dialect used to parse the input expression.
6504        **opts: other options to use to parse the input expressions.
6505
6506    Returns:
6507        A new Select instance with the subquery expression included.
6508    """
6509
6510    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6511    return Select().from_(expression, dialect=dialect, **opts)
6512
6513
6514@t.overload
6515def column(
6516    col: str | Identifier,
6517    table: t.Optional[str | Identifier] = None,
6518    db: t.Optional[str | Identifier] = None,
6519    catalog: t.Optional[str | Identifier] = None,
6520    *,
6521    fields: t.Collection[t.Union[str, Identifier]],
6522    quoted: t.Optional[bool] = None,
6523    copy: bool = True,
6524) -> Dot:
6525    pass
6526
6527
6528@t.overload
6529def column(
6530    col: str | Identifier,
6531    table: t.Optional[str | Identifier] = None,
6532    db: t.Optional[str | Identifier] = None,
6533    catalog: t.Optional[str | Identifier] = None,
6534    *,
6535    fields: Lit[None] = None,
6536    quoted: t.Optional[bool] = None,
6537    copy: bool = True,
6538) -> Column:
6539    pass
6540
6541
6542def column(
6543    col,
6544    table=None,
6545    db=None,
6546    catalog=None,
6547    *,
6548    fields=None,
6549    quoted=None,
6550    copy=True,
6551):
6552    """
6553    Build a Column.
6554
6555    Args:
6556        col: Column name.
6557        table: Table name.
6558        db: Database name.
6559        catalog: Catalog name.
6560        fields: Additional fields using dots.
6561        quoted: Whether to force quotes on the column's identifiers.
6562        copy: Whether to copy identifiers if passed in.
6563
6564    Returns:
6565        The new Column instance.
6566    """
6567    this = Column(
6568        this=to_identifier(col, quoted=quoted, copy=copy),
6569        table=to_identifier(table, quoted=quoted, copy=copy),
6570        db=to_identifier(db, quoted=quoted, copy=copy),
6571        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6572    )
6573
6574    if fields:
6575        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6576    return this
6577
6578
6579def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6580    """Cast an expression to a data type.
6581
6582    Example:
6583        >>> cast('x + 1', 'int').sql()
6584        'CAST(x + 1 AS INT)'
6585
6586    Args:
6587        expression: The expression to cast.
6588        to: The datatype to cast to.
6589        copy: Whether to copy the supplied expressions.
6590
6591    Returns:
6592        The new Cast instance.
6593    """
6594    expression = maybe_parse(expression, copy=copy, **opts)
6595    data_type = DataType.build(to, copy=copy, **opts)
6596    expression = Cast(this=expression, to=data_type)
6597    expression.type = data_type
6598    return expression
6599
6600
6601def table_(
6602    table: Identifier | str,
6603    db: t.Optional[Identifier | str] = None,
6604    catalog: t.Optional[Identifier | str] = None,
6605    quoted: t.Optional[bool] = None,
6606    alias: t.Optional[Identifier | str] = None,
6607) -> Table:
6608    """Build a Table.
6609
6610    Args:
6611        table: Table name.
6612        db: Database name.
6613        catalog: Catalog name.
6614        quote: Whether to force quotes on the table's identifiers.
6615        alias: Table's alias.
6616
6617    Returns:
6618        The new Table instance.
6619    """
6620    return Table(
6621        this=to_identifier(table, quoted=quoted) if table else None,
6622        db=to_identifier(db, quoted=quoted) if db else None,
6623        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6624        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6625    )
6626
6627
6628def values(
6629    values: t.Iterable[t.Tuple[t.Any, ...]],
6630    alias: t.Optional[str] = None,
6631    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6632) -> Values:
6633    """Build VALUES statement.
6634
6635    Example:
6636        >>> values([(1, '2')]).sql()
6637        "VALUES (1, '2')"
6638
6639    Args:
6640        values: values statements that will be converted to SQL
6641        alias: optional alias
6642        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6643         If either are provided then an alias is also required.
6644
6645    Returns:
6646        Values: the Values expression object
6647    """
6648    if columns and not alias:
6649        raise ValueError("Alias is required when providing columns")
6650
6651    return Values(
6652        expressions=[convert(tup) for tup in values],
6653        alias=(
6654            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6655            if columns
6656            else (TableAlias(this=to_identifier(alias)) if alias else None)
6657        ),
6658    )
6659
6660
6661def var(name: t.Optional[ExpOrStr]) -> Var:
6662    """Build a SQL variable.
6663
6664    Example:
6665        >>> repr(var('x'))
6666        'Var(this=x)'
6667
6668        >>> repr(var(column('x', table='y')))
6669        'Var(this=x)'
6670
6671    Args:
6672        name: The name of the var or an expression who's name will become the var.
6673
6674    Returns:
6675        The new variable node.
6676    """
6677    if not name:
6678        raise ValueError("Cannot convert empty name into var.")
6679
6680    if isinstance(name, Expression):
6681        name = name.name
6682    return Var(this=name)
6683
6684
6685def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6686    """Build ALTER TABLE... RENAME... expression
6687
6688    Args:
6689        old_name: The old name of the table
6690        new_name: The new name of the table
6691
6692    Returns:
6693        Alter table expression
6694    """
6695    old_table = to_table(old_name)
6696    new_table = to_table(new_name)
6697    return AlterTable(
6698        this=old_table,
6699        actions=[
6700            RenameTable(this=new_table),
6701        ],
6702    )
6703
6704
6705def rename_column(
6706    table_name: str | Table,
6707    old_column_name: str | Column,
6708    new_column_name: str | Column,
6709    exists: t.Optional[bool] = None,
6710) -> AlterTable:
6711    """Build ALTER TABLE... RENAME COLUMN... expression
6712
6713    Args:
6714        table_name: Name of the table
6715        old_column: The old name of the column
6716        new_column: The new name of the column
6717        exists: Whether to add the `IF EXISTS` clause
6718
6719    Returns:
6720        Alter table expression
6721    """
6722    table = to_table(table_name)
6723    old_column = to_column(old_column_name)
6724    new_column = to_column(new_column_name)
6725    return AlterTable(
6726        this=table,
6727        actions=[
6728            RenameColumn(this=old_column, to=new_column, exists=exists),
6729        ],
6730    )
6731
6732
6733def convert(value: t.Any, copy: bool = False) -> Expression:
6734    """Convert a python value into an expression object.
6735
6736    Raises an error if a conversion is not possible.
6737
6738    Args:
6739        value: A python object.
6740        copy: Whether to copy `value` (only applies to Expressions and collections).
6741
6742    Returns:
6743        Expression: the equivalent expression object.
6744    """
6745    if isinstance(value, Expression):
6746        return maybe_copy(value, copy)
6747    if isinstance(value, str):
6748        return Literal.string(value)
6749    if isinstance(value, bool):
6750        return Boolean(this=value)
6751    if value is None or (isinstance(value, float) and math.isnan(value)):
6752        return null()
6753    if isinstance(value, numbers.Number):
6754        return Literal.number(value)
6755    if isinstance(value, datetime.datetime):
6756        datetime_literal = Literal.string(
6757            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6758        )
6759        return TimeStrToTime(this=datetime_literal)
6760    if isinstance(value, datetime.date):
6761        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6762        return DateStrToDate(this=date_literal)
6763    if isinstance(value, tuple):
6764        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6765    if isinstance(value, list):
6766        return Array(expressions=[convert(v, copy=copy) for v in value])
6767    if isinstance(value, dict):
6768        return Map(
6769            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6770            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6771        )
6772    raise ValueError(f"Cannot convert {value}")
6773
6774
6775def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6776    """
6777    Replace children of an expression with the result of a lambda fun(child) -> exp.
6778    """
6779    for k, v in expression.args.items():
6780        is_list_arg = type(v) is list
6781
6782        child_nodes = v if is_list_arg else [v]
6783        new_child_nodes = []
6784
6785        for cn in child_nodes:
6786            if isinstance(cn, Expression):
6787                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6788                    new_child_nodes.append(child_node)
6789                    child_node.parent = expression
6790                    child_node.arg_key = k
6791            else:
6792                new_child_nodes.append(cn)
6793
6794        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
6795
6796
6797def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6798    """
6799    Return all table names referenced through columns in an expression.
6800
6801    Example:
6802        >>> import sqlglot
6803        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6804        ['a', 'c']
6805
6806    Args:
6807        expression: expression to find table names.
6808        exclude: a table name to exclude
6809
6810    Returns:
6811        A list of unique names.
6812    """
6813    return {
6814        table
6815        for table in (column.table for column in expression.find_all(Column))
6816        if table and table != exclude
6817    }
6818
6819
6820def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6821    """Get the full name of a table as a string.
6822
6823    Args:
6824        table: Table expression node or string.
6825        dialect: The dialect to generate the table name for.
6826        identify: Determines when an identifier should be quoted. Possible values are:
6827            False (default): Never quote, except in cases where it's mandatory by the dialect.
6828            True: Always quote.
6829
6830    Examples:
6831        >>> from sqlglot import exp, parse_one
6832        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6833        'a.b.c'
6834
6835    Returns:
6836        The table name.
6837    """
6838
6839    table = maybe_parse(table, into=Table, dialect=dialect)
6840
6841    if not table:
6842        raise ValueError(f"Cannot parse {table}")
6843
6844    return ".".join(
6845        (
6846            part.sql(dialect=dialect, identify=True, copy=False)
6847            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6848            else part.name
6849        )
6850        for part in table.parts
6851    )
6852
6853
6854def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6855    """Returns a case normalized table name without quotes.
6856
6857    Args:
6858        table: the table to normalize
6859        dialect: the dialect to use for normalization rules
6860        copy: whether to copy the expression.
6861
6862    Examples:
6863        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6864        'A-B.c'
6865    """
6866    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6867
6868    return ".".join(
6869        p.name
6870        for p in normalize_identifiers(
6871            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6872        ).parts
6873    )
6874
6875
6876def replace_tables(
6877    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6878) -> E:
6879    """Replace all tables in expression according to the mapping.
6880
6881    Args:
6882        expression: expression node to be transformed and replaced.
6883        mapping: mapping of table names.
6884        dialect: the dialect of the mapping table
6885        copy: whether to copy the expression.
6886
6887    Examples:
6888        >>> from sqlglot import exp, parse_one
6889        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6890        'SELECT * FROM c /* a.b */'
6891
6892    Returns:
6893        The mapped expression.
6894    """
6895
6896    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6897
6898    def _replace_tables(node: Expression) -> Expression:
6899        if isinstance(node, Table):
6900            original = normalize_table_name(node, dialect=dialect)
6901            new_name = mapping.get(original)
6902
6903            if new_name:
6904                table = to_table(
6905                    new_name,
6906                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6907                    dialect=dialect,
6908                )
6909                table.add_comments([original])
6910                return table
6911        return node
6912
6913    return expression.transform(_replace_tables, copy=copy)
6914
6915
6916def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6917    """Replace placeholders in an expression.
6918
6919    Args:
6920        expression: expression node to be transformed and replaced.
6921        args: positional names that will substitute unnamed placeholders in the given order.
6922        kwargs: keyword arguments that will substitute named placeholders.
6923
6924    Examples:
6925        >>> from sqlglot import exp, parse_one
6926        >>> replace_placeholders(
6927        ...     parse_one("select * from :tbl where ? = ?"),
6928        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6929        ... ).sql()
6930        "SELECT * FROM foo WHERE str_col = 'b'"
6931
6932    Returns:
6933        The mapped expression.
6934    """
6935
6936    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6937        if isinstance(node, Placeholder):
6938            if node.name:
6939                new_name = kwargs.get(node.name)
6940                if new_name:
6941                    return convert(new_name)
6942            else:
6943                try:
6944                    return convert(next(args))
6945                except StopIteration:
6946                    pass
6947        return node
6948
6949    return expression.transform(_replace_placeholders, iter(args), **kwargs)
6950
6951
6952def expand(
6953    expression: Expression,
6954    sources: t.Dict[str, Subqueryable],
6955    dialect: DialectType = None,
6956    copy: bool = True,
6957) -> Expression:
6958    """Transforms an expression by expanding all referenced sources into subqueries.
6959
6960    Examples:
6961        >>> from sqlglot import parse_one
6962        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6963        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6964
6965        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6966        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6967
6968    Args:
6969        expression: The expression to expand.
6970        sources: A dictionary of name to Subqueryables.
6971        dialect: The dialect of the sources dict.
6972        copy: Whether to copy the expression during transformation. Defaults to True.
6973
6974    Returns:
6975        The transformed expression.
6976    """
6977    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6978
6979    def _expand(node: Expression):
6980        if isinstance(node, Table):
6981            name = normalize_table_name(node, dialect=dialect)
6982            source = sources.get(name)
6983            if source:
6984                subquery = source.subquery(node.alias or name)
6985                subquery.comments = [f"source: {name}"]
6986                return subquery.transform(_expand, copy=False)
6987        return node
6988
6989    return expression.transform(_expand, copy=copy)
6990
6991
6992def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6993    """
6994    Returns a Func expression.
6995
6996    Examples:
6997        >>> func("abs", 5).sql()
6998        'ABS(5)'
6999
7000        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7001        'CAST(5 AS DOUBLE)'
7002
7003    Args:
7004        name: the name of the function to build.
7005        args: the args used to instantiate the function of interest.
7006        copy: whether to copy the argument expressions.
7007        dialect: the source dialect.
7008        kwargs: the kwargs used to instantiate the function of interest.
7009
7010    Note:
7011        The arguments `args` and `kwargs` are mutually exclusive.
7012
7013    Returns:
7014        An instance of the function of interest, or an anonymous function, if `name` doesn't
7015        correspond to an existing `sqlglot.expressions.Func` class.
7016    """
7017    if args and kwargs:
7018        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7019
7020    from sqlglot.dialects.dialect import Dialect
7021
7022    dialect = Dialect.get_or_raise(dialect)
7023
7024    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7025    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7026
7027    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7028    if constructor:
7029        if converted:
7030            if "dialect" in constructor.__code__.co_varnames:
7031                function = constructor(converted, dialect=dialect)
7032            else:
7033                function = constructor(converted)
7034        elif constructor.__name__ == "from_arg_list":
7035            function = constructor.__self__(**kwargs)  # type: ignore
7036        else:
7037            constructor = FUNCTION_BY_NAME.get(name.upper())
7038            if constructor:
7039                function = constructor(**kwargs)
7040            else:
7041                raise ValueError(
7042                    f"Unable to convert '{name}' into a Func. Either manually construct "
7043                    "the Func expression of interest or parse the function call."
7044                )
7045    else:
7046        kwargs = kwargs or {"expressions": converted}
7047        function = Anonymous(this=name, **kwargs)
7048
7049    for error_message in function.error_messages(converted):
7050        raise ValueError(error_message)
7051
7052    return function
7053
7054
7055def case(
7056    expression: t.Optional[ExpOrStr] = None,
7057    **opts,
7058) -> Case:
7059    """
7060    Initialize a CASE statement.
7061
7062    Example:
7063        case().when("a = 1", "foo").else_("bar")
7064
7065    Args:
7066        expression: Optionally, the input expression (not all dialects support this)
7067        **opts: Extra keyword arguments for parsing `expression`
7068    """
7069    if expression is not None:
7070        this = maybe_parse(expression, **opts)
7071    else:
7072        this = None
7073    return Case(this=this, ifs=[])
7074
7075
7076def cast_unless(
7077    expression: ExpOrStr,
7078    to: DATA_TYPE,
7079    *types: DATA_TYPE,
7080    **opts: t.Any,
7081) -> Expression | Cast:
7082    """
7083    Cast an expression to a data type unless it is a specified type.
7084
7085    Args:
7086        expression: The expression to cast.
7087        to: The data type to cast to.
7088        **types: The types to exclude from casting.
7089        **opts: Extra keyword arguments for parsing `expression`
7090    """
7091    expr = maybe_parse(expression, **opts)
7092    if expr.is_type(*types):
7093        return expr
7094    return cast(expr, to, **opts)
7095
7096
7097def array(
7098    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7099) -> Array:
7100    """
7101    Returns an array.
7102
7103    Examples:
7104        >>> array(1, 'x').sql()
7105        'ARRAY(1, x)'
7106
7107    Args:
7108        expressions: the expressions to add to the array.
7109        copy: whether to copy the argument expressions.
7110        dialect: the source dialect.
7111        kwargs: the kwargs used to instantiate the function of interest.
7112
7113    Returns:
7114        An array expression.
7115    """
7116    return Array(
7117        expressions=[
7118            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7119            for expression in expressions
7120        ]
7121    )
7122
7123
7124def tuple_(
7125    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7126) -> Tuple:
7127    """
7128    Returns an tuple.
7129
7130    Examples:
7131        >>> tuple_(1, 'x').sql()
7132        '(1, x)'
7133
7134    Args:
7135        expressions: the expressions to add to the tuple.
7136        copy: whether to copy the argument expressions.
7137        dialect: the source dialect.
7138        kwargs: the kwargs used to instantiate the function of interest.
7139
7140    Returns:
7141        A tuple expression.
7142    """
7143    return Tuple(
7144        expressions=[
7145            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7146            for expression in expressions
7147        ]
7148    )
7149
7150
7151def true() -> Boolean:
7152    """
7153    Returns a true Boolean expression.
7154    """
7155    return Boolean(this=True)
7156
7157
7158def false() -> Boolean:
7159    """
7160    Returns a false Boolean expression.
7161    """
7162    return Boolean(this=False)
7163
7164
7165def null() -> Null:
7166    """
7167    Returns a Null expression.
7168    """
7169    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    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
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.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>}
INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIME: 'TIME'>, <Type.DATE32: 'DATE32'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <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 = {"expressions": True}
arg_types = {'expressions': True}
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 AddMonths(Func):
5201class AddMonths(Func):
5202    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5205class Nvl2(Func):
5206    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5210class Predict(Func):
5211    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5214class Pow(Binary, Func):
5215    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5218class PercentileCont(AggFunc):
5219    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5222class PercentileDisc(AggFunc):
5223    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5226class Quantile(AggFunc):
5227    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5230class ApproxQuantile(Quantile):
5231    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):
5234class Rand(Func):
5235    _sql_names = ["RAND", "RANDOM"]
5236    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5239class Randn(Func):
5240    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5243class RangeN(Func):
5244    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5247class ReadCSV(Func):
5248    _sql_names = ["READ_CSV"]
5249    is_var_len_args = True
5250    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5253class Reduce(Func):
5254    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):
5257class RegexpExtract(Func):
5258    arg_types = {
5259        "this": True,
5260        "expression": True,
5261        "position": False,
5262        "occurrence": False,
5263        "parameters": False,
5264        "group": False,
5265    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5268class RegexpReplace(Func):
5269    arg_types = {
5270        "this": True,
5271        "expression": True,
5272        "replacement": False,
5273        "position": False,
5274        "occurrence": False,
5275        "parameters": False,
5276        "modifiers": False,
5277    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5280class RegexpLike(Binary, Func):
5281    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5284class RegexpILike(Binary, Func):
5285    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5290class RegexpSplit(Func):
5291    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5294class Repeat(Func):
5295    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5300class Round(Func):
5301    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5304class RowNumber(Func):
5305    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5308class SafeDivide(Func):
5309    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5312class SHA(Func):
5313    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5316class SHA2(Func):
5317    _sql_names = ["SHA2"]
5318    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5321class Sign(Func):
5322    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5325class SortArray(Func):
5326    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5329class Split(Func):
5330    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5335class Substring(Func):
5336    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5339class StandardHash(Func):
5340    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5343class StartsWith(Func):
5344    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5345    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5348class StrPosition(Func):
5349    arg_types = {
5350        "this": True,
5351        "substr": True,
5352        "position": False,
5353        "instance": False,
5354    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5357class StrToDate(Func):
5358    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5361class StrToTime(Func):
5362    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5367class StrToUnix(Func):
5368    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5373class StrToMap(Func):
5374    arg_types = {
5375        "this": True,
5376        "pair_delim": False,
5377        "key_value_delim": False,
5378        "duplicate_resolution_callback": False,
5379    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5382class NumberToStr(Func):
5383    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5386class FromBase(Func):
5387    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5390class Struct(Func):
5391    arg_types = {"expressions": False}
5392    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5395class StructExtract(Func):
5396    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5401class Stuff(Func):
5402    _sql_names = ["STUFF", "INSERT"]
5403    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):
5406class Sum(AggFunc):
5407    pass
key = 'sum'
class Sqrt(Func):
5410class Sqrt(Func):
5411    pass
key = 'sqrt'
class Stddev(AggFunc):
5414class Stddev(AggFunc):
5415    pass
key = 'stddev'
class StddevPop(AggFunc):
5418class StddevPop(AggFunc):
5419    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5422class StddevSamp(AggFunc):
5423    pass
key = 'stddevsamp'
class TimeToStr(Func):
5426class TimeToStr(Func):
5427    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5430class TimeToTimeStr(Func):
5431    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5434class TimeToUnix(Func):
5435    pass
key = 'timetounix'
class TimeStrToDate(Func):
5438class TimeStrToDate(Func):
5439    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5442class TimeStrToTime(Func):
5443    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5446class TimeStrToUnix(Func):
5447    pass
key = 'timestrtounix'
class Trim(Func):
5450class Trim(Func):
5451    arg_types = {
5452        "this": True,
5453        "expression": False,
5454        "position": False,
5455        "collation": False,
5456    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5459class TsOrDsAdd(Func, TimeUnit):
5460    # return_type is used to correctly cast the arguments of this expression when transpiling it
5461    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5462
5463    @property
5464    def return_type(self) -> DataType:
5465        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
5463    @property
5464    def return_type(self) -> DataType:
5465        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5468class TsOrDsDiff(Func, TimeUnit):
5469    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5472class TsOrDsToDateStr(Func):
5473    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5476class TsOrDsToDate(Func):
5477    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5480class TsOrDsToTime(Func):
5481    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5484class TsOrDiToDi(Func):
5485    pass
key = 'tsorditodi'
class Unhex(Func):
5488class Unhex(Func):
5489    pass
key = 'unhex'
class UnixDate(Func):
5493class UnixDate(Func):
5494    pass
key = 'unixdate'
class UnixToStr(Func):
5497class UnixToStr(Func):
5498    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5503class UnixToTime(Func):
5504    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5505
5506    SECONDS = Literal.number(0)
5507    DECIS = Literal.number(1)
5508    CENTIS = Literal.number(2)
5509    MILLIS = Literal.number(3)
5510    DECIMILLIS = Literal.number(4)
5511    CENTIMILLIS = Literal.number(5)
5512    MICROS = Literal.number(6)
5513    DECIMICROS = Literal.number(7)
5514    CENTIMICROS = Literal.number(8)
5515    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):
5518class UnixToTimeStr(Func):
5519    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5522class TimestampFromParts(Func):
5523    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5524    arg_types = {
5525        "year": True,
5526        "month": True,
5527        "day": True,
5528        "hour": True,
5529        "min": True,
5530        "sec": True,
5531        "nano": False,
5532        "zone": False,
5533        "milli": False,
5534    }
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):
5537class Upper(Func):
5538    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5541class Variance(AggFunc):
5542    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5545class VariancePop(AggFunc):
5546    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5549class Week(Func):
5550    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5553class XMLTable(Func):
5554    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):
5557class Year(Func):
5558    pass
key = 'year'
class Use(Expression):
5561class Use(Expression):
5562    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5565class Merge(Expression):
5566    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):
5569class When(Func):
5570    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):
5575class NextValueFor(Func):
5576    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <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 'Sign'>, <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'>, 'ADD_MONTHS': <class 'AddMonths'>, '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'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, '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:
5616def maybe_parse(
5617    sql_or_expression: ExpOrStr,
5618    *,
5619    into: t.Optional[IntoType] = None,
5620    dialect: DialectType = None,
5621    prefix: t.Optional[str] = None,
5622    copy: bool = False,
5623    **opts,
5624) -> Expression:
5625    """Gracefully handle a possible string or expression.
5626
5627    Example:
5628        >>> maybe_parse("1")
5629        Literal(this=1, is_string=False)
5630        >>> maybe_parse(to_identifier("x"))
5631        Identifier(this=x, quoted=False)
5632
5633    Args:
5634        sql_or_expression: the SQL code string or an expression
5635        into: the SQLGlot Expression to parse into
5636        dialect: the dialect used to parse the input expressions (in the case that an
5637            input expression is a SQL string).
5638        prefix: a string to prefix the sql with before it gets parsed
5639            (automatically includes a space)
5640        copy: whether to copy the expression.
5641        **opts: other options to use to parse the input expressions (again, in the case
5642            that an input expression is a SQL string).
5643
5644    Returns:
5645        Expression: the parsed or given expression.
5646    """
5647    if isinstance(sql_or_expression, Expression):
5648        if copy:
5649            return sql_or_expression.copy()
5650        return sql_or_expression
5651
5652    if sql_or_expression is None:
5653        raise ParseError("SQL cannot be None")
5654
5655    import sqlglot
5656
5657    sql = str(sql_or_expression)
5658    if prefix:
5659        sql = f"{prefix} {sql}"
5660
5661    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):
5674def maybe_copy(instance, copy=True):
5675    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:
5889def union(
5890    left: ExpOrStr,
5891    right: ExpOrStr,
5892    distinct: bool = True,
5893    dialect: DialectType = None,
5894    copy: bool = True,
5895    **opts,
5896) -> Union:
5897    """
5898    Initializes a syntax tree from one UNION expression.
5899
5900    Example:
5901        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5902        'SELECT * FROM foo UNION SELECT * FROM bla'
5903
5904    Args:
5905        left: the SQL code string corresponding to the left-hand side.
5906            If an `Expression` instance is passed, it will be used as-is.
5907        right: the SQL code string corresponding to the right-hand side.
5908            If an `Expression` instance is passed, it will be used as-is.
5909        distinct: set the DISTINCT flag if and only if this is true.
5910        dialect: the dialect used to parse the input expression.
5911        copy: whether to copy the expression.
5912        opts: other options to use to parse the input expressions.
5913
5914    Returns:
5915        The new Union instance.
5916    """
5917    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5918    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5919
5920    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:
5923def intersect(
5924    left: ExpOrStr,
5925    right: ExpOrStr,
5926    distinct: bool = True,
5927    dialect: DialectType = None,
5928    copy: bool = True,
5929    **opts,
5930) -> Intersect:
5931    """
5932    Initializes a syntax tree from one INTERSECT expression.
5933
5934    Example:
5935        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5936        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5937
5938    Args:
5939        left: the SQL code string corresponding to the left-hand side.
5940            If an `Expression` instance is passed, it will be used as-is.
5941        right: the SQL code string corresponding to the right-hand side.
5942            If an `Expression` instance is passed, it will be used as-is.
5943        distinct: set the DISTINCT flag if and only if this is true.
5944        dialect: the dialect used to parse the input expression.
5945        copy: whether to copy the expression.
5946        opts: other options to use to parse the input expressions.
5947
5948    Returns:
5949        The new Intersect instance.
5950    """
5951    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5952    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5953
5954    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:
5957def except_(
5958    left: ExpOrStr,
5959    right: ExpOrStr,
5960    distinct: bool = True,
5961    dialect: DialectType = None,
5962    copy: bool = True,
5963    **opts,
5964) -> Except:
5965    """
5966    Initializes a syntax tree from one EXCEPT expression.
5967
5968    Example:
5969        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5970        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5971
5972    Args:
5973        left: the SQL code string corresponding to the left-hand side.
5974            If an `Expression` instance is passed, it will be used as-is.
5975        right: the SQL code string corresponding to the right-hand side.
5976            If an `Expression` instance is passed, it will be used as-is.
5977        distinct: set the DISTINCT flag if and only if this is true.
5978        dialect: the dialect used to parse the input expression.
5979        copy: whether to copy the expression.
5980        opts: other options to use to parse the input expressions.
5981
5982    Returns:
5983        The new Except instance.
5984    """
5985    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5986    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5987
5988    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:
5991def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5992    """
5993    Initializes a syntax tree from one or multiple SELECT expressions.
5994
5995    Example:
5996        >>> select("col1", "col2").from_("tbl").sql()
5997        'SELECT col1, col2 FROM tbl'
5998
5999    Args:
6000        *expressions: the SQL code string to parse as the expressions of a
6001            SELECT statement. If an Expression instance is passed, this is used as-is.
6002        dialect: the dialect used to parse the input expressions (in the case that an
6003            input expression is a SQL string).
6004        **opts: other options to use to parse the input expressions (again, in the case
6005            that an input expression is a SQL string).
6006
6007    Returns:
6008        Select: the syntax tree for the SELECT statement.
6009    """
6010    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:
6013def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6014    """
6015    Initializes a syntax tree from a FROM expression.
6016
6017    Example:
6018        >>> from_("tbl").select("col1", "col2").sql()
6019        'SELECT col1, col2 FROM tbl'
6020
6021    Args:
6022        *expression: the SQL code string to parse as the FROM expressions of a
6023            SELECT statement. If an Expression instance is passed, this is used as-is.
6024        dialect: the dialect used to parse the input expression (in the case that the
6025            input expression is a SQL string).
6026        **opts: other options to use to parse the input expressions (again, in the case
6027            that the input expression is a SQL string).
6028
6029    Returns:
6030        Select: the syntax tree for the SELECT statement.
6031    """
6032    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:
6035def update(
6036    table: str | Table,
6037    properties: dict,
6038    where: t.Optional[ExpOrStr] = None,
6039    from_: t.Optional[ExpOrStr] = None,
6040    dialect: DialectType = None,
6041    **opts,
6042) -> Update:
6043    """
6044    Creates an update statement.
6045
6046    Example:
6047        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6048        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6049
6050    Args:
6051        *properties: dictionary of properties to set which are
6052            auto converted to sql objects eg None -> NULL
6053        where: sql conditional parsed into a WHERE statement
6054        from_: sql statement parsed into a FROM statement
6055        dialect: the dialect used to parse the input expressions.
6056        **opts: other options to use to parse the input expressions.
6057
6058    Returns:
6059        Update: the syntax tree for the UPDATE statement.
6060    """
6061    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6062    update_expr.set(
6063        "expressions",
6064        [
6065            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6066            for k, v in properties.items()
6067        ],
6068    )
6069    if from_:
6070        update_expr.set(
6071            "from",
6072            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6073        )
6074    if isinstance(where, Condition):
6075        where = Where(this=where)
6076    if where:
6077        update_expr.set(
6078            "where",
6079            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6080        )
6081    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:
6084def delete(
6085    table: ExpOrStr,
6086    where: t.Optional[ExpOrStr] = None,
6087    returning: t.Optional[ExpOrStr] = None,
6088    dialect: DialectType = None,
6089    **opts,
6090) -> Delete:
6091    """
6092    Builds a delete statement.
6093
6094    Example:
6095        >>> delete("my_table", where="id > 1").sql()
6096        'DELETE FROM my_table WHERE id > 1'
6097
6098    Args:
6099        where: sql conditional parsed into a WHERE statement
6100        returning: sql conditional parsed into a RETURNING statement
6101        dialect: the dialect used to parse the input expressions.
6102        **opts: other options to use to parse the input expressions.
6103
6104    Returns:
6105        Delete: the syntax tree for the DELETE statement.
6106    """
6107    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6108    if where:
6109        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6110    if returning:
6111        delete_expr = t.cast(
6112            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6113        )
6114    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:
6117def insert(
6118    expression: ExpOrStr,
6119    into: ExpOrStr,
6120    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6121    overwrite: t.Optional[bool] = None,
6122    returning: t.Optional[ExpOrStr] = None,
6123    dialect: DialectType = None,
6124    copy: bool = True,
6125    **opts,
6126) -> Insert:
6127    """
6128    Builds an INSERT statement.
6129
6130    Example:
6131        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6132        'INSERT INTO tbl VALUES (1, 2, 3)'
6133
6134    Args:
6135        expression: the sql string or expression of the INSERT statement
6136        into: the tbl to insert data to.
6137        columns: optionally the table's column names.
6138        overwrite: whether to INSERT OVERWRITE or not.
6139        returning: sql conditional parsed into a RETURNING statement
6140        dialect: the dialect used to parse the input expressions.
6141        copy: whether to copy the expression.
6142        **opts: other options to use to parse the input expressions.
6143
6144    Returns:
6145        Insert: the syntax tree for the INSERT statement.
6146    """
6147    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6148    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6149
6150    if columns:
6151        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6152
6153    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6154
6155    if returning:
6156        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6157
6158    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:
6161def condition(
6162    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6163) -> Condition:
6164    """
6165    Initialize a logical condition expression.
6166
6167    Example:
6168        >>> condition("x=1").sql()
6169        'x = 1'
6170
6171        This is helpful for composing larger logical syntax trees:
6172        >>> where = condition("x=1")
6173        >>> where = where.and_("y=1")
6174        >>> Select().from_("tbl").select("*").where(where).sql()
6175        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6176
6177    Args:
6178        *expression: the SQL code string to parse.
6179            If an Expression instance is passed, this is used as-is.
6180        dialect: the dialect used to parse the input expression (in the case that the
6181            input expression is a SQL string).
6182        copy: Whether to copy `expression` (only applies to expressions).
6183        **opts: other options to use to parse the input expressions (again, in the case
6184            that the input expression is a SQL string).
6185
6186    Returns:
6187        The new Condition instance
6188    """
6189    return maybe_parse(
6190        expression,
6191        into=Condition,
6192        dialect=dialect,
6193        copy=copy,
6194        **opts,
6195    )

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

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

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

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

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

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

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

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

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

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:
7125def tuple_(
7126    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7127) -> Tuple:
7128    """
7129    Returns an tuple.
7130
7131    Examples:
7132        >>> tuple_(1, 'x').sql()
7133        '(1, x)'
7134
7135    Args:
7136        expressions: the expressions to add to the tuple.
7137        copy: whether to copy the argument expressions.
7138        dialect: the source dialect.
7139        kwargs: the kwargs used to instantiate the function of interest.
7140
7141    Returns:
7142        A tuple expression.
7143    """
7144    return Tuple(
7145        expressions=[
7146            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7147            for expression in expressions
7148        ]
7149    )

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:
7152def true() -> Boolean:
7153    """
7154    Returns a true Boolean expression.
7155    """
7156    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7159def false() -> Boolean:
7160    """
7161    Returns a false Boolean expression.
7162    """
7163    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7166def null() -> Null:
7167    """
7168    Returns a Null expression.
7169    """
7170    return Null()

Returns a Null expression.