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

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines what arguments (child nodes) are supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
 95    def __init__(self, **args: t.Any):
 96        self.args: t.Dict[str, t.Any] = args
 97        self.parent: t.Optional[Expression] = None
 98        self.arg_key: t.Optional[str] = None
 99        self.comments: t.Optional[t.List[str]] = None
100        self._type: t.Optional[DataType] = None
101        self._meta: t.Optional[t.Dict[str, t.Any]] = None
102        self._hash: t.Optional[int] = None
103
104        for arg_key, value in self.args.items():
105            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
this: Any

Retrieves the argument with key "this".

expression: Any

Retrieves the argument with key "expression".

expressions: List[Any]

Retrieves the argument with key "expressions".

def text(self, key) -> str:
145    def text(self, key) -> str:
146        """
147        Returns a textual representation of the argument corresponding to "key". This can only be used
148        for args that are strings or leaf Expression instances, such as identifiers and literals.
149        """
150        field = self.args.get(key)
151        if isinstance(field, str):
152            return field
153        if isinstance(field, (Identifier, Literal, Var)):
154            return field.this
155        if isinstance(field, (Star, Null)):
156            return field.name
157        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

Checks whether a Literal expression is a string.

is_number: bool

Checks whether a Literal expression is a number.

is_int: bool

Checks whether a Literal expression is an integer.

is_star: bool

Checks whether an expression is a star.

alias: str

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

alias_column_names: List[str]
name: str
alias_or_name: str
output_name: str

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]
def is_type(self, *dtypes) -> bool:
243    def is_type(self, *dtypes) -> bool:
244        return self.type is not None and self.type.is_type(*dtypes)
meta: Dict[str, Any]
def copy(self):
265    def copy(self):
266        """
267        Returns a deep copy of the expression.
268        """
269        new = deepcopy(self)
270        new.parent = self.parent
271        return new

Returns a deep copy of the expression.

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

Returns the depth of this tree.

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

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]

Returns the parent select statement.

same_parent: bool

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
487    def flatten(self, unnest=True):
488        """
489        Returns a generator which yields child nodes who's parents are the same class.
490
491        A AND B AND C -> [A, B, C]
492        """
493        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
494            if not type(node) is self.__class__:
495                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes who's parents are the same class.

A AND B AND C -> [A, B, C]

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
503    def sql(self, dialect: DialectType = None, **opts) -> str:
504        """
505        Returns SQL string representation of this tree.
506
507        Args:
508            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
509            opts: other `sqlglot.generator.Generator` options.
510
511        Returns:
512            The SQL string.
513        """
514        from sqlglot.dialects import Dialect
515
516        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):
542    def transform(self, fun, *args, copy=True, **kwargs):
543        """
544        Recursively visits all tree nodes (excluding already transformed ones)
545        and applies the given transformation function to each node.
546
547        Args:
548            fun (function): a function which takes a node as an argument and returns a
549                new transformed node or the same node without modifications. If the function
550                returns None, then the corresponding node will be removed from the syntax tree.
551            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
552                modified in place.
553
554        Returns:
555            The transformed tree.
556        """
557        node = self.copy() if copy else self
558        new_node = fun(node, *args, **kwargs)
559
560        if new_node is None or not isinstance(new_node, Expression):
561            return new_node
562        if new_node is not node:
563            new_node.parent = node.parent
564            return new_node
565
566        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
567        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):
577    def replace(self, expression):
578        """
579        Swap out this expression with a new expression.
580
581        For example::
582
583            >>> tree = Select().select("x").from_("tbl")
584            >>> tree.find(Column).replace(Column(this="y"))
585            (COLUMN this: y)
586            >>> tree.sql()
587            'SELECT y FROM tbl'
588
589        Args:
590            expression: new node
591
592        Returns:
593            The new expression or expressions.
594        """
595        if not self.parent:
596            return expression
597
598        parent = self.parent
599        self.parent = None
600
601        replace_children(parent, lambda child: expression if child is self else child)
602        return expression

Swap out this expression with a new expression.

For example::

>>> tree = Select().select("x").from_("tbl")
>>> tree.find(Column).replace(Column(this="y"))
(COLUMN this: y)
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
604    def pop(self: E) -> E:
605        """
606        Remove this expression from its AST.
607
608        Returns:
609            The popped expression.
610        """
611        self.replace(None)
612        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
673    @classmethod
674    def load(cls, obj):
675        """
676        Load a dict (as returned by `Expression.dump`) into an Expression instance.
677        """
678        from sqlglot.serde import load
679
680        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:
682    def and_(
683        self,
684        *expressions: t.Optional[ExpOrStr],
685        dialect: DialectType = None,
686        copy: bool = True,
687        **opts,
688    ) -> Condition:
689        """
690        AND this condition with one or multiple expressions.
691
692        Example:
693            >>> condition("x=1").and_("y=1").sql()
694            'x = 1 AND y = 1'
695
696        Args:
697            *expressions: the SQL code strings to parse.
698                If an `Expression` instance is passed, it will be used as-is.
699            dialect: the dialect used to parse the input expression.
700            copy: whether or not to copy the involved expressions (only applies to Expressions).
701            opts: other options to use to parse the input expressions.
702
703        Returns:
704            The new And condition.
705        """
706        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1").and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
708    def or_(
709        self,
710        *expressions: t.Optional[ExpOrStr],
711        dialect: DialectType = None,
712        copy: bool = True,
713        **opts,
714    ) -> Condition:
715        """
716        OR this condition with one or multiple expressions.
717
718        Example:
719            >>> condition("x=1").or_("y=1").sql()
720            'x = 1 OR y = 1'
721
722        Args:
723            *expressions: the SQL code strings to parse.
724                If an `Expression` instance is passed, it will be used as-is.
725            dialect: the dialect used to parse the input expression.
726            copy: whether or not to copy the involved expressions (only applies to Expressions).
727            opts: other options to use to parse the input expressions.
728
729        Returns:
730            The new Or condition.
731        """
732        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1").or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
734    def not_(self, copy: bool = True):
735        """
736        Wrap this condition with NOT.
737
738        Example:
739            >>> condition("x=1").not_().sql()
740            'NOT x = 1'
741
742        Args:
743            copy: whether or not to copy this object.
744
745        Returns:
746            The new Not instance.
747        """
748        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether or not to copy this object.
Returns:

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
750    def as_(
751        self,
752        alias: str | Identifier,
753        quoted: t.Optional[bool] = None,
754        dialect: DialectType = None,
755        copy: bool = True,
756        **opts,
757    ) -> Alias:
758        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:
783    def isin(
784        self,
785        *expressions: t.Any,
786        query: t.Optional[ExpOrStr] = None,
787        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
788        copy: bool = True,
789        **opts,
790    ) -> In:
791        return In(
792            this=maybe_copy(self, copy),
793            expressions=[convert(e, copy=copy) for e in expressions],
794            query=maybe_parse(query, copy=copy, **opts) if query else None,
795            unnest=Unnest(
796                expressions=[
797                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
798                ]
799            )
800            if unnest
801            else None,
802        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
804    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
805        return Between(
806            this=maybe_copy(self, copy),
807            low=convert(low, copy=copy, **opts),
808            high=convert(high, copy=copy, **opts),
809        )
def is_( self, other: Union[str, Expression]) -> Is:
811    def is_(self, other: ExpOrStr) -> Is:
812        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
814    def like(self, other: ExpOrStr) -> Like:
815        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
817    def ilike(self, other: ExpOrStr) -> ILike:
818        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
820    def eq(self, other: t.Any) -> EQ:
821        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
823    def neq(self, other: t.Any) -> NEQ:
824        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
826    def rlike(self, other: ExpOrStr) -> RegexpLike:
827        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
829    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
830        div = self._binop(Div, other)
831        div.args["typed"] = typed
832        div.args["safe"] = safe
833        return div
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
916class Condition(Expression):
917    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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):
1087class Create(DDL):
1088    arg_types = {
1089        "with": False,
1090        "this": True,
1091        "kind": True,
1092        "expression": False,
1093        "exists": False,
1094        "properties": False,
1095        "replace": False,
1096        "unique": False,
1097        "indexes": False,
1098        "no_schema_binding": False,
1099        "begin": False,
1100        "end": False,
1101        "clone": False,
1102    }
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False}
key = 'create'
class Clone(Expression):
1108class Clone(Expression):
1109    arg_types = {
1110        "this": True,
1111        "when": False,
1112        "kind": False,
1113        "shallow": False,
1114        "expression": False,
1115        "copy": False,
1116    }
arg_types = {'this': True, 'when': False, 'kind': False, 'shallow': False, 'expression': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1119class Describe(Expression):
1120    arg_types = {"this": True, "kind": False, "expressions": False}
arg_types = {'this': True, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1123class Kill(Expression):
1124    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1127class Pragma(Expression):
1128    pass
key = 'pragma'
class Set(Expression):
1131class Set(Expression):
1132    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class SetItem(Expression):
1135class SetItem(Expression):
1136    arg_types = {
1137        "this": False,
1138        "expressions": False,
1139        "kind": False,
1140        "collate": False,  # MySQL SET NAMES statement
1141        "global": False,
1142    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1145class Show(Expression):
1146    arg_types = {
1147        "this": True,
1148        "target": False,
1149        "offset": False,
1150        "limit": False,
1151        "like": False,
1152        "where": False,
1153        "db": False,
1154        "scope": False,
1155        "scope_kind": False,
1156        "full": False,
1157        "mutex": False,
1158        "query": False,
1159        "channel": False,
1160        "global": False,
1161        "log": False,
1162        "position": False,
1163        "types": False,
1164    }
arg_types = {'this': True, 'target': False, 'offset': False, 'limit': 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):
1167class UserDefinedFunction(Expression):
1168    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1171class CharacterSet(Expression):
1172    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1175class With(Expression):
1176    arg_types = {"expressions": True, "recursive": False}
1177
1178    @property
1179    def recursive(self) -> bool:
1180        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
key = 'with'
class WithinGroup(Expression):
1183class WithinGroup(Expression):
1184    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1189class CTE(DerivedTable):
1190    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1193class TableAlias(Expression):
1194    arg_types = {"this": False, "columns": False}
1195
1196    @property
1197    def columns(self):
1198        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
key = 'tablealias'
class BitString(Condition):
1201class BitString(Condition):
1202    pass
key = 'bitstring'
class HexString(Condition):
1205class HexString(Condition):
1206    pass
key = 'hexstring'
class ByteString(Condition):
1209class ByteString(Condition):
1210    pass
key = 'bytestring'
class RawString(Condition):
1213class RawString(Condition):
1214    pass
key = 'rawstring'
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
db: str
catalog: str
output_name: str

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]

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]
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    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1287class RenameTable(Expression):
1288    pass
key = 'renametable'
class SwapTable(Expression):
1291class SwapTable(Expression):
1292    pass
key = 'swaptable'
class Comment(Expression):
1295class Comment(Expression):
1296    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False}
key = 'comment'
class Comprehension(Expression):
1299class Comprehension(Expression):
1300    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
arg_types = {'this': True, 'expression': True, 'iterator': True, 'condition': False}
key = 'comprehension'
class MergeTreeTTLAction(Expression):
1304class MergeTreeTTLAction(Expression):
1305    arg_types = {
1306        "this": True,
1307        "delete": False,
1308        "recompress": False,
1309        "to_disk": False,
1310        "to_volume": False,
1311    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1315class MergeTreeTTL(Expression):
1316    arg_types = {
1317        "expressions": True,
1318        "where": False,
1319        "group": False,
1320        "aggregates": False,
1321    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1325class IndexConstraintOption(Expression):
1326    arg_types = {
1327        "key_block_size": False,
1328        "using": False,
1329        "parser": False,
1330        "comment": False,
1331        "visible": False,
1332        "engine_attr": False,
1333        "secondary_engine_attr": False,
1334    }
arg_types = {'key_block_size': False, 'using': False, 'parser': False, 'comment': False, 'visible': False, 'engine_attr': False, 'secondary_engine_attr': False}
key = 'indexconstraintoption'
class ColumnConstraint(Expression):
1337class ColumnConstraint(Expression):
1338    arg_types = {"this": False, "kind": True}
1339
1340    @property
1341    def kind(self) -> ColumnConstraintKind:
1342        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1345class ColumnConstraintKind(Expression):
1346    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1349class AutoIncrementColumnConstraint(ColumnConstraintKind):
1350    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1353class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1354    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1357class CaseSpecificColumnConstraint(ColumnConstraintKind):
1358    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1361class CharacterSetColumnConstraint(ColumnConstraintKind):
1362    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1365class CheckColumnConstraint(ColumnConstraintKind):
1366    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1369class ClusteredColumnConstraint(ColumnConstraintKind):
1370    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1373class CollateColumnConstraint(ColumnConstraintKind):
1374    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1377class CommentColumnConstraint(ColumnConstraintKind):
1378    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1381class CompressColumnConstraint(ColumnConstraintKind):
1382    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1385class DateFormatColumnConstraint(ColumnConstraintKind):
1386    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1389class DefaultColumnConstraint(ColumnConstraintKind):
1390    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1393class EncodeColumnConstraint(ColumnConstraintKind):
1394    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1397class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1398    # this: True -> ALWAYS, this: False -> BY DEFAULT
1399    arg_types = {
1400        "this": False,
1401        "expression": False,
1402        "on_null": False,
1403        "start": False,
1404        "increment": False,
1405        "minvalue": False,
1406        "maxvalue": False,
1407        "cycle": False,
1408    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1411class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1412    arg_types = {"start": True, "hidden": False}
arg_types = {'start': True, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1416class IndexColumnConstraint(ColumnConstraintKind):
1417    arg_types = {
1418        "this": False,
1419        "schema": True,
1420        "kind": False,
1421        "index_type": False,
1422        "options": False,
1423    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1426class InlineLengthColumnConstraint(ColumnConstraintKind):
1427    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1430class NonClusteredColumnConstraint(ColumnConstraintKind):
1431    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1434class NotForReplicationColumnConstraint(ColumnConstraintKind):
1435    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1438class NotNullColumnConstraint(ColumnConstraintKind):
1439    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1443class OnUpdateColumnConstraint(ColumnConstraintKind):
1444    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1447class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1448    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1451class TitleColumnConstraint(ColumnConstraintKind):
1452    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1455class UniqueColumnConstraint(ColumnConstraintKind):
1456    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1459class UppercaseColumnConstraint(ColumnConstraintKind):
1460    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1463class PathColumnConstraint(ColumnConstraintKind):
1464    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1469class ComputedColumnConstraint(ColumnConstraintKind):
1470    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1473class Constraint(Expression):
1474    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1477class Delete(DML):
1478    arg_types = {
1479        "with": False,
1480        "this": False,
1481        "using": False,
1482        "where": False,
1483        "returning": False,
1484        "limit": False,
1485        "tables": False,  # Multiple-Table Syntax (MySQL)
1486    }
1487
1488    def delete(
1489        self,
1490        table: ExpOrStr,
1491        dialect: DialectType = None,
1492        copy: bool = True,
1493        **opts,
1494    ) -> Delete:
1495        """
1496        Create a DELETE expression or replace the table on an existing DELETE expression.
1497
1498        Example:
1499            >>> delete("tbl").sql()
1500            'DELETE FROM tbl'
1501
1502        Args:
1503            table: the table from which to delete.
1504            dialect: the dialect used to parse the input expression.
1505            copy: if `False`, modify this expression instance in-place.
1506            opts: other options to use to parse the input expressions.
1507
1508        Returns:
1509            Delete: the modified expression.
1510        """
1511        return _apply_builder(
1512            expression=table,
1513            instance=self,
1514            arg="this",
1515            dialect=dialect,
1516            into=Table,
1517            copy=copy,
1518            **opts,
1519        )
1520
1521    def where(
1522        self,
1523        *expressions: t.Optional[ExpOrStr],
1524        append: bool = True,
1525        dialect: DialectType = None,
1526        copy: bool = True,
1527        **opts,
1528    ) -> Delete:
1529        """
1530        Append to or set the WHERE expressions.
1531
1532        Example:
1533            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1534            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1535
1536        Args:
1537            *expressions: the SQL code strings to parse.
1538                If an `Expression` instance is passed, it will be used as-is.
1539                Multiple expressions are combined with an AND operator.
1540            append: if `True`, AND the new expressions to any existing expression.
1541                Otherwise, this resets the expression.
1542            dialect: the dialect used to parse the input expressions.
1543            copy: if `False`, modify this expression instance in-place.
1544            opts: other options to use to parse the input expressions.
1545
1546        Returns:
1547            Delete: the modified expression.
1548        """
1549        return _apply_conjunction_builder(
1550            *expressions,
1551            instance=self,
1552            arg="where",
1553            append=append,
1554            into=Where,
1555            dialect=dialect,
1556            copy=copy,
1557            **opts,
1558        )
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:
1488    def delete(
1489        self,
1490        table: ExpOrStr,
1491        dialect: DialectType = None,
1492        copy: bool = True,
1493        **opts,
1494    ) -> Delete:
1495        """
1496        Create a DELETE expression or replace the table on an existing DELETE expression.
1497
1498        Example:
1499            >>> delete("tbl").sql()
1500            'DELETE FROM tbl'
1501
1502        Args:
1503            table: the table from which to delete.
1504            dialect: the dialect used to parse the input expression.
1505            copy: if `False`, modify this expression instance in-place.
1506            opts: other options to use to parse the input expressions.
1507
1508        Returns:
1509            Delete: the modified expression.
1510        """
1511        return _apply_builder(
1512            expression=table,
1513            instance=self,
1514            arg="this",
1515            dialect=dialect,
1516            into=Table,
1517            copy=copy,
1518            **opts,
1519        )

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

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):
1561class Drop(Expression):
1562    arg_types = {
1563        "this": False,
1564        "kind": False,
1565        "exists": False,
1566        "temporary": False,
1567        "materialized": False,
1568        "cascade": False,
1569        "constraints": False,
1570        "purge": False,
1571    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1574class Filter(Expression):
1575    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1578class Check(Expression):
1579    pass
key = 'check'
class Connect(Expression):
1583class Connect(Expression):
1584    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1587class Prior(Expression):
1588    pass
key = 'prior'
class Directory(Expression):
1591class Directory(Expression):
1592    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1593    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1596class ForeignKey(Expression):
1597    arg_types = {
1598        "expressions": True,
1599        "reference": False,
1600        "delete": False,
1601        "update": False,
1602    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1605class ColumnPrefix(Expression):
1606    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1609class PrimaryKey(Expression):
1610    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1615class Into(Expression):
1616    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1619class From(Expression):
1620    @property
1621    def name(self) -> str:
1622        return self.this.name
1623
1624    @property
1625    def alias_or_name(self) -> str:
1626        return self.this.alias_or_name
name: str
alias_or_name: str
key = 'from'
class Having(Expression):
1629class Having(Expression):
1630    pass
key = 'having'
class Hint(Expression):
1633class Hint(Expression):
1634    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1637class JoinHint(Expression):
1638    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1641class Identifier(Expression):
1642    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1643
1644    @property
1645    def quoted(self) -> bool:
1646        return bool(self.args.get("quoted"))
1647
1648    @property
1649    def hashable_args(self) -> t.Any:
1650        return (self.this, self.quoted)
1651
1652    @property
1653    def output_name(self) -> str:
1654        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
hashable_args: Any
output_name: str

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):
1658class Opclass(Expression):
1659    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1662class Index(Expression):
1663    arg_types = {
1664        "this": False,
1665        "table": False,
1666        "using": False,
1667        "where": False,
1668        "columns": False,
1669        "unique": False,
1670        "primary": False,
1671        "amp": False,  # teradata
1672        "partition_by": False,  # teradata
1673        "where": False,  # postgres partial indexes
1674    }
arg_types = {'this': False, 'table': False, 'using': False, 'where': False, 'columns': False, 'unique': False, 'primary': False, 'amp': False, 'partition_by': False}
key = 'index'
class Insert(DDL, DML):
1677class Insert(DDL, DML):
1678    arg_types = {
1679        "with": False,
1680        "this": True,
1681        "expression": False,
1682        "conflict": False,
1683        "returning": False,
1684        "overwrite": False,
1685        "exists": False,
1686        "partition": False,
1687        "alternative": False,
1688        "where": False,
1689        "ignore": False,
1690        "by_name": False,
1691    }
1692
1693    def with_(
1694        self,
1695        alias: ExpOrStr,
1696        as_: ExpOrStr,
1697        recursive: t.Optional[bool] = None,
1698        append: bool = True,
1699        dialect: DialectType = None,
1700        copy: bool = True,
1701        **opts,
1702    ) -> Insert:
1703        """
1704        Append to or set the common table expressions.
1705
1706        Example:
1707            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1708            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1709
1710        Args:
1711            alias: the SQL code string to parse as the table name.
1712                If an `Expression` instance is passed, this is used as-is.
1713            as_: the SQL code string to parse as the table expression.
1714                If an `Expression` instance is passed, it will be used as-is.
1715            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1716            append: if `True`, add to any existing expressions.
1717                Otherwise, this resets the expressions.
1718            dialect: the dialect used to parse the input expression.
1719            copy: if `False`, modify this expression instance in-place.
1720            opts: other options to use to parse the input expressions.
1721
1722        Returns:
1723            The modified expression.
1724        """
1725        return _apply_cte_builder(
1726            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1727        )
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:
1693    def with_(
1694        self,
1695        alias: ExpOrStr,
1696        as_: ExpOrStr,
1697        recursive: t.Optional[bool] = None,
1698        append: bool = True,
1699        dialect: DialectType = None,
1700        copy: bool = True,
1701        **opts,
1702    ) -> Insert:
1703        """
1704        Append to or set the common table expressions.
1705
1706        Example:
1707            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1708            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1709
1710        Args:
1711            alias: the SQL code string to parse as the table name.
1712                If an `Expression` instance is passed, this is used as-is.
1713            as_: the SQL code string to parse as the table expression.
1714                If an `Expression` instance is passed, it will be used as-is.
1715            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1716            append: if `True`, add to any existing expressions.
1717                Otherwise, this resets the expressions.
1718            dialect: the dialect used to parse the input expression.
1719            copy: if `False`, modify this expression instance in-place.
1720            opts: other options to use to parse the input expressions.
1721
1722        Returns:
1723            The modified expression.
1724        """
1725        return _apply_cte_builder(
1726            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1727        )

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):
1730class OnConflict(Expression):
1731    arg_types = {
1732        "duplicate": False,
1733        "expressions": False,
1734        "nothing": False,
1735        "key": False,
1736        "constraint": False,
1737    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1740class Returning(Expression):
1741    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1745class Introducer(Expression):
1746    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1750class National(Expression):
1751    pass
key = 'national'
class LoadData(Expression):
1754class LoadData(Expression):
1755    arg_types = {
1756        "this": True,
1757        "local": False,
1758        "overwrite": False,
1759        "inpath": True,
1760        "partition": False,
1761        "input_format": False,
1762        "serde": False,
1763    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1766class Partition(Expression):
1767    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1770class Fetch(Expression):
1771    arg_types = {
1772        "direction": False,
1773        "count": False,
1774        "percent": False,
1775        "with_ties": False,
1776    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1779class Group(Expression):
1780    arg_types = {
1781        "expressions": False,
1782        "grouping_sets": False,
1783        "cube": False,
1784        "rollup": False,
1785        "totals": False,
1786        "all": False,
1787    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1790class Lambda(Expression):
1791    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1794class Limit(Expression):
1795    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1798class Literal(Condition):
1799    arg_types = {"this": True, "is_string": True}
1800
1801    @property
1802    def hashable_args(self) -> t.Any:
1803        return (self.this, self.args.get("is_string"))
1804
1805    @classmethod
1806    def number(cls, number) -> Literal:
1807        return cls(this=str(number), is_string=False)
1808
1809    @classmethod
1810    def string(cls, string) -> Literal:
1811        return cls(this=str(string), is_string=True)
1812
1813    @property
1814    def output_name(self) -> str:
1815        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
@classmethod
def number(cls, number) -> Literal:
1805    @classmethod
1806    def number(cls, number) -> Literal:
1807        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1809    @classmethod
1810    def string(cls, string) -> Literal:
1811        return cls(this=str(string), is_string=True)
output_name: str

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):
1818class Join(Expression):
1819    arg_types = {
1820        "this": True,
1821        "on": False,
1822        "side": False,
1823        "kind": False,
1824        "using": False,
1825        "method": False,
1826        "global": False,
1827        "hint": False,
1828    }
1829
1830    @property
1831    def method(self) -> str:
1832        return self.text("method").upper()
1833
1834    @property
1835    def kind(self) -> str:
1836        return self.text("kind").upper()
1837
1838    @property
1839    def side(self) -> str:
1840        return self.text("side").upper()
1841
1842    @property
1843    def hint(self) -> str:
1844        return self.text("hint").upper()
1845
1846    @property
1847    def alias_or_name(self) -> str:
1848        return self.this.alias_or_name
1849
1850    def on(
1851        self,
1852        *expressions: t.Optional[ExpOrStr],
1853        append: bool = True,
1854        dialect: DialectType = None,
1855        copy: bool = True,
1856        **opts,
1857    ) -> Join:
1858        """
1859        Append to or set the ON expressions.
1860
1861        Example:
1862            >>> import sqlglot
1863            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1864            'JOIN x ON y = 1'
1865
1866        Args:
1867            *expressions: the SQL code strings to parse.
1868                If an `Expression` instance is passed, it will be used as-is.
1869                Multiple expressions are combined with an AND operator.
1870            append: if `True`, AND the new expressions to any existing expression.
1871                Otherwise, this resets the expression.
1872            dialect: the dialect used to parse the input expressions.
1873            copy: if `False`, modify this expression instance in-place.
1874            opts: other options to use to parse the input expressions.
1875
1876        Returns:
1877            The modified Join expression.
1878        """
1879        join = _apply_conjunction_builder(
1880            *expressions,
1881            instance=self,
1882            arg="on",
1883            append=append,
1884            dialect=dialect,
1885            copy=copy,
1886            **opts,
1887        )
1888
1889        if join.kind == "CROSS":
1890            join.set("kind", None)
1891
1892        return join
1893
1894    def using(
1895        self,
1896        *expressions: t.Optional[ExpOrStr],
1897        append: bool = True,
1898        dialect: DialectType = None,
1899        copy: bool = True,
1900        **opts,
1901    ) -> Join:
1902        """
1903        Append to or set the USING expressions.
1904
1905        Example:
1906            >>> import sqlglot
1907            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1908            'JOIN x USING (foo, bla)'
1909
1910        Args:
1911            *expressions: the SQL code strings to parse.
1912                If an `Expression` instance is passed, it will be used as-is.
1913            append: if `True`, concatenate the new expressions to the existing "using" list.
1914                Otherwise, this resets the expression.
1915            dialect: the dialect used to parse the input expressions.
1916            copy: if `False`, modify this expression instance in-place.
1917            opts: other options to use to parse the input expressions.
1918
1919        Returns:
1920            The modified Join expression.
1921        """
1922        join = _apply_list_builder(
1923            *expressions,
1924            instance=self,
1925            arg="using",
1926            append=append,
1927            dialect=dialect,
1928            copy=copy,
1929            **opts,
1930        )
1931
1932        if join.kind == "CROSS":
1933            join.set("kind", None)
1934
1935        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
kind: str
side: str
hint: str
alias_or_name: str
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:
1850    def on(
1851        self,
1852        *expressions: t.Optional[ExpOrStr],
1853        append: bool = True,
1854        dialect: DialectType = None,
1855        copy: bool = True,
1856        **opts,
1857    ) -> Join:
1858        """
1859        Append to or set the ON expressions.
1860
1861        Example:
1862            >>> import sqlglot
1863            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1864            'JOIN x ON y = 1'
1865
1866        Args:
1867            *expressions: the SQL code strings to parse.
1868                If an `Expression` instance is passed, it will be used as-is.
1869                Multiple expressions are combined with an AND operator.
1870            append: if `True`, AND the new expressions to any existing expression.
1871                Otherwise, this resets the expression.
1872            dialect: the dialect used to parse the input expressions.
1873            copy: if `False`, modify this expression instance in-place.
1874            opts: other options to use to parse the input expressions.
1875
1876        Returns:
1877            The modified Join expression.
1878        """
1879        join = _apply_conjunction_builder(
1880            *expressions,
1881            instance=self,
1882            arg="on",
1883            append=append,
1884            dialect=dialect,
1885            copy=copy,
1886            **opts,
1887        )
1888
1889        if join.kind == "CROSS":
1890            join.set("kind", None)
1891
1892        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:
1894    def using(
1895        self,
1896        *expressions: t.Optional[ExpOrStr],
1897        append: bool = True,
1898        dialect: DialectType = None,
1899        copy: bool = True,
1900        **opts,
1901    ) -> Join:
1902        """
1903        Append to or set the USING expressions.
1904
1905        Example:
1906            >>> import sqlglot
1907            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1908            'JOIN x USING (foo, bla)'
1909
1910        Args:
1911            *expressions: the SQL code strings to parse.
1912                If an `Expression` instance is passed, it will be used as-is.
1913            append: if `True`, concatenate the new expressions to the existing "using" list.
1914                Otherwise, this resets the expression.
1915            dialect: the dialect used to parse the input expressions.
1916            copy: if `False`, modify this expression instance in-place.
1917            opts: other options to use to parse the input expressions.
1918
1919        Returns:
1920            The modified Join expression.
1921        """
1922        join = _apply_list_builder(
1923            *expressions,
1924            instance=self,
1925            arg="using",
1926            append=append,
1927            dialect=dialect,
1928            copy=copy,
1929            **opts,
1930        )
1931
1932        if join.kind == "CROSS":
1933            join.set("kind", None)
1934
1935        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):
1938class Lateral(UDTF):
1939    arg_types = {"this": True, "view": False, "outer": False, "alias": False}
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False}
key = 'lateral'
class MatchRecognize(Expression):
1942class MatchRecognize(Expression):
1943    arg_types = {
1944        "partition_by": False,
1945        "order": False,
1946        "measures": False,
1947        "rows": False,
1948        "after": False,
1949        "pattern": False,
1950        "define": False,
1951        "alias": False,
1952    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1957class Final(Expression):
1958    pass
key = 'final'
class Offset(Expression):
1961class Offset(Expression):
1962    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1965class Order(Expression):
1966    arg_types = {"this": False, "expressions": True}
arg_types = {'this': False, 'expressions': True}
key = 'order'
class Cluster(Order):
1971class Cluster(Order):
1972    pass
key = 'cluster'
class Distribute(Order):
1975class Distribute(Order):
1976    pass
key = 'distribute'
class Sort(Order):
1979class Sort(Order):
1980    pass
key = 'sort'
class Ordered(Expression):
1983class Ordered(Expression):
1984    arg_types = {"this": True, "desc": False, "nulls_first": True}
arg_types = {'this': True, 'desc': False, 'nulls_first': True}
key = 'ordered'
class Property(Expression):
1987class Property(Expression):
1988    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
1991class AlgorithmProperty(Property):
1992    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
1995class AutoIncrementProperty(Property):
1996    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class BlockCompressionProperty(Property):
1999class BlockCompressionProperty(Property):
2000    arg_types = {"autotemp": False, "always": False, "default": True, "manual": True, "never": True}
arg_types = {'autotemp': False, 'always': False, 'default': True, 'manual': True, 'never': True}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2003class CharacterSetProperty(Property):
2004    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2007class ChecksumProperty(Property):
2008    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2011class CollateProperty(Property):
2012    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2015class CopyGrantsProperty(Property):
2016    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2019class DataBlocksizeProperty(Property):
2020    arg_types = {
2021        "size": False,
2022        "units": False,
2023        "minimum": False,
2024        "maximum": False,
2025        "default": False,
2026    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2029class DefinerProperty(Property):
2030    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2033class DistKeyProperty(Property):
2034    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2037class DistStyleProperty(Property):
2038    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2041class EngineProperty(Property):
2042    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2045class HeapProperty(Property):
2046    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2049class ToTableProperty(Property):
2050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2053class ExecuteAsProperty(Property):
2054    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2057class ExternalProperty(Property):
2058    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2061class FallbackProperty(Property):
2062    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2065class FileFormatProperty(Property):
2066    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2069class FreespaceProperty(Property):
2070    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InputModelProperty(Property):
2073class InputModelProperty(Property):
2074    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2077class OutputModelProperty(Property):
2078    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2081class IsolatedLoadingProperty(Property):
2082    arg_types = {
2083        "no": True,
2084        "concurrent": True,
2085        "for_all": True,
2086        "for_insert": True,
2087        "for_none": True,
2088    }
arg_types = {'no': True, 'concurrent': True, 'for_all': True, 'for_insert': True, 'for_none': True}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2091class JournalProperty(Property):
2092    arg_types = {
2093        "no": False,
2094        "dual": False,
2095        "before": False,
2096        "local": False,
2097        "after": False,
2098    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2101class LanguageProperty(Property):
2102    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2106class ClusteredByProperty(Property):
2107    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2110class DictProperty(Property):
2111    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2114class DictSubProperty(Property):
2115    pass
key = 'dictsubproperty'
class DictRange(Property):
2118class DictRange(Property):
2119    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2124class OnCluster(Property):
2125    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2128class LikeProperty(Property):
2129    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2132class LocationProperty(Property):
2133    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2136class LockingProperty(Property):
2137    arg_types = {
2138        "this": False,
2139        "kind": True,
2140        "for_or_in": False,
2141        "lock_type": True,
2142        "override": False,
2143    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2146class LogProperty(Property):
2147    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2150class MaterializedProperty(Property):
2151    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2154class MergeBlockRatioProperty(Property):
2155    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):
2158class NoPrimaryIndexProperty(Property):
2159    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2162class OnProperty(Property):
2163    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2166class OnCommitProperty(Property):
2167    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2170class PartitionedByProperty(Property):
2171    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2175class PartitionBoundSpec(Expression):
2176    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2177    arg_types = {
2178        "this": False,
2179        "expression": False,
2180        "from_expressions": False,
2181        "to_expressions": False,
2182    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2185class PartitionedOfProperty(Property):
2186    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2187    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2190class RemoteWithConnectionModelProperty(Property):
2191    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2194class ReturnsProperty(Property):
2195    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2198class RowFormatProperty(Property):
2199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2202class RowFormatDelimitedProperty(Property):
2203    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2204    arg_types = {
2205        "fields": False,
2206        "escaped": False,
2207        "collection_items": False,
2208        "map_keys": False,
2209        "lines": False,
2210        "null": False,
2211        "serde": False,
2212    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2215class RowFormatSerdeProperty(Property):
2216    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2220class QueryTransform(Expression):
2221    arg_types = {
2222        "expressions": True,
2223        "command_script": True,
2224        "schema": False,
2225        "row_format_before": False,
2226        "record_writer": False,
2227        "row_format_after": False,
2228        "record_reader": False,
2229    }
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):
2232class SampleProperty(Property):
2233    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2236class SchemaCommentProperty(Property):
2237    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2240class SerdeProperties(Property):
2241    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2244class SetProperty(Property):
2245    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SettingsProperty(Property):
2248class SettingsProperty(Property):
2249    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2252class SortKeyProperty(Property):
2253    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlSecurityProperty(Property):
2256class SqlSecurityProperty(Property):
2257    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2260class StabilityProperty(Property):
2261    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2264class TemporaryProperty(Property):
2265    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2268class TransformModelProperty(Property):
2269    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2272class TransientProperty(Property):
2273    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2276class VolatileProperty(Property):
2277    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2280class WithDataProperty(Property):
2281    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2284class WithJournalTableProperty(Property):
2285    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2288class WithSystemVersioningProperty(Property):
2289    # this -> history table name, expression -> data consistency check
2290    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2293class Properties(Expression):
2294    arg_types = {"expressions": True}
2295
2296    NAME_TO_PROPERTY = {
2297        "ALGORITHM": AlgorithmProperty,
2298        "AUTO_INCREMENT": AutoIncrementProperty,
2299        "CHARACTER SET": CharacterSetProperty,
2300        "CLUSTERED_BY": ClusteredByProperty,
2301        "COLLATE": CollateProperty,
2302        "COMMENT": SchemaCommentProperty,
2303        "DEFINER": DefinerProperty,
2304        "DISTKEY": DistKeyProperty,
2305        "DISTSTYLE": DistStyleProperty,
2306        "ENGINE": EngineProperty,
2307        "EXECUTE AS": ExecuteAsProperty,
2308        "FORMAT": FileFormatProperty,
2309        "LANGUAGE": LanguageProperty,
2310        "LOCATION": LocationProperty,
2311        "PARTITIONED_BY": PartitionedByProperty,
2312        "RETURNS": ReturnsProperty,
2313        "ROW_FORMAT": RowFormatProperty,
2314        "SORTKEY": SortKeyProperty,
2315    }
2316
2317    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2318
2319    # CREATE property locations
2320    # Form: schema specified
2321    #   create [POST_CREATE]
2322    #     table a [POST_NAME]
2323    #     (b int) [POST_SCHEMA]
2324    #     with ([POST_WITH])
2325    #     index (b) [POST_INDEX]
2326    #
2327    # Form: alias selection
2328    #   create [POST_CREATE]
2329    #     table a [POST_NAME]
2330    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2331    #     index (c) [POST_INDEX]
2332    class Location(AutoName):
2333        POST_CREATE = auto()
2334        POST_NAME = auto()
2335        POST_SCHEMA = auto()
2336        POST_WITH = auto()
2337        POST_ALIAS = auto()
2338        POST_EXPRESSION = auto()
2339        POST_INDEX = auto()
2340        UNSUPPORTED = auto()
2341
2342    @classmethod
2343    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2344        expressions = []
2345        for key, value in properties_dict.items():
2346            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2347            if property_cls:
2348                expressions.append(property_cls(this=convert(value)))
2349            else:
2350                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2351
2352        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:
2342    @classmethod
2343    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2344        expressions = []
2345        for key, value in properties_dict.items():
2346            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2347            if property_cls:
2348                expressions.append(property_cls(this=convert(value)))
2349            else:
2350                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2351
2352        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2332    class Location(AutoName):
2333        POST_CREATE = auto()
2334        POST_NAME = auto()
2335        POST_SCHEMA = auto()
2336        POST_WITH = auto()
2337        POST_ALIAS = auto()
2338        POST_EXPRESSION = auto()
2339        POST_INDEX = auto()
2340        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):
2355class Qualify(Expression):
2356    pass
key = 'qualify'
class InputOutputFormat(Expression):
2359class InputOutputFormat(Expression):
2360    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2364class Return(Expression):
2365    pass
key = 'return'
class Reference(Expression):
2368class Reference(Expression):
2369    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2372class Tuple(Expression):
2373    arg_types = {"expressions": False}
2374
2375    def isin(
2376        self,
2377        *expressions: t.Any,
2378        query: t.Optional[ExpOrStr] = None,
2379        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2380        copy: bool = True,
2381        **opts,
2382    ) -> In:
2383        return In(
2384            this=maybe_copy(self, copy),
2385            expressions=[convert(e, copy=copy) for e in expressions],
2386            query=maybe_parse(query, copy=copy, **opts) if query else None,
2387            unnest=Unnest(
2388                expressions=[
2389                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2390                ]
2391            )
2392            if unnest
2393            else None,
2394        )
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:
2375    def isin(
2376        self,
2377        *expressions: t.Any,
2378        query: t.Optional[ExpOrStr] = None,
2379        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2380        copy: bool = True,
2381        **opts,
2382    ) -> In:
2383        return In(
2384            this=maybe_copy(self, copy),
2385            expressions=[convert(e, copy=copy) for e in expressions],
2386            query=maybe_parse(query, copy=copy, **opts) if query else None,
2387            unnest=Unnest(
2388                expressions=[
2389                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2390                ]
2391            )
2392            if unnest
2393            else None,
2394        )
key = 'tuple'
class Subqueryable(Unionable):
2397class Subqueryable(Unionable):
2398    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2399        """
2400        Convert this expression to an aliased expression that can be used as a Subquery.
2401
2402        Example:
2403            >>> subquery = Select().select("x").from_("tbl").subquery()
2404            >>> Select().select("x").from_(subquery).sql()
2405            'SELECT x FROM (SELECT x FROM tbl)'
2406
2407        Args:
2408            alias (str | Identifier): an optional alias for the subquery
2409            copy (bool): if `False`, modify this expression instance in-place.
2410
2411        Returns:
2412            Alias: the subquery
2413        """
2414        instance = maybe_copy(self, copy)
2415        if not isinstance(alias, Expression):
2416            alias = TableAlias(this=to_identifier(alias)) if alias else None
2417
2418        return Subquery(this=instance, alias=alias)
2419
2420    def limit(
2421        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2422    ) -> Select:
2423        raise NotImplementedError
2424
2425    @property
2426    def ctes(self):
2427        with_ = self.args.get("with")
2428        if not with_:
2429            return []
2430        return with_.expressions
2431
2432    @property
2433    def selects(self) -> t.List[Expression]:
2434        raise NotImplementedError("Subqueryable objects must implement `selects`")
2435
2436    @property
2437    def named_selects(self) -> t.List[str]:
2438        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2439
2440    def select(
2441        self,
2442        *expressions: t.Optional[ExpOrStr],
2443        append: bool = True,
2444        dialect: DialectType = None,
2445        copy: bool = True,
2446        **opts,
2447    ) -> Subqueryable:
2448        raise NotImplementedError("Subqueryable objects must implement `select`")
2449
2450    def with_(
2451        self,
2452        alias: ExpOrStr,
2453        as_: ExpOrStr,
2454        recursive: t.Optional[bool] = None,
2455        append: bool = True,
2456        dialect: DialectType = None,
2457        copy: bool = True,
2458        **opts,
2459    ) -> Subqueryable:
2460        """
2461        Append to or set the common table expressions.
2462
2463        Example:
2464            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2465            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2466
2467        Args:
2468            alias: the SQL code string to parse as the table name.
2469                If an `Expression` instance is passed, this is used as-is.
2470            as_: the SQL code string to parse as the table expression.
2471                If an `Expression` instance is passed, it will be used as-is.
2472            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2473            append: if `True`, add to any existing expressions.
2474                Otherwise, this resets the expressions.
2475            dialect: the dialect used to parse the input expression.
2476            copy: if `False`, modify this expression instance in-place.
2477            opts: other options to use to parse the input expressions.
2478
2479        Returns:
2480            The modified expression.
2481        """
2482        return _apply_cte_builder(
2483            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2484        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2398    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2399        """
2400        Convert this expression to an aliased expression that can be used as a Subquery.
2401
2402        Example:
2403            >>> subquery = Select().select("x").from_("tbl").subquery()
2404            >>> Select().select("x").from_(subquery).sql()
2405            'SELECT x FROM (SELECT x FROM tbl)'
2406
2407        Args:
2408            alias (str | Identifier): an optional alias for the subquery
2409            copy (bool): if `False`, modify this expression instance in-place.
2410
2411        Returns:
2412            Alias: the subquery
2413        """
2414        instance = maybe_copy(self, copy)
2415        if not isinstance(alias, Expression):
2416            alias = TableAlias(this=to_identifier(alias)) if alias else None
2417
2418        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:
2420    def limit(
2421        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2422    ) -> Select:
2423        raise NotImplementedError
ctes
selects: List[Expression]
named_selects: List[str]
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:
2440    def select(
2441        self,
2442        *expressions: t.Optional[ExpOrStr],
2443        append: bool = True,
2444        dialect: DialectType = None,
2445        copy: bool = True,
2446        **opts,
2447    ) -> Subqueryable:
2448        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:
2450    def with_(
2451        self,
2452        alias: ExpOrStr,
2453        as_: ExpOrStr,
2454        recursive: t.Optional[bool] = None,
2455        append: bool = True,
2456        dialect: DialectType = None,
2457        copy: bool = True,
2458        **opts,
2459    ) -> Subqueryable:
2460        """
2461        Append to or set the common table expressions.
2462
2463        Example:
2464            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2465            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2466
2467        Args:
2468            alias: the SQL code string to parse as the table name.
2469                If an `Expression` instance is passed, this is used as-is.
2470            as_: the SQL code string to parse as the table expression.
2471                If an `Expression` instance is passed, it will be used as-is.
2472            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2473            append: if `True`, add to any existing expressions.
2474                Otherwise, this resets the expressions.
2475            dialect: the dialect used to parse the input expression.
2476            copy: if `False`, modify this expression instance in-place.
2477            opts: other options to use to parse the input expressions.
2478
2479        Returns:
2480            The modified expression.
2481        """
2482        return _apply_cte_builder(
2483            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2484        )

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):
2512class WithTableHint(Expression):
2513    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2517class IndexTableHint(Expression):
2518    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class Table(Expression):
2521class Table(Expression):
2522    arg_types = {
2523        "this": True,
2524        "alias": False,
2525        "db": False,
2526        "catalog": False,
2527        "laterals": False,
2528        "joins": False,
2529        "pivots": False,
2530        "hints": False,
2531        "system_time": False,
2532        "version": False,
2533        "format": False,
2534        "pattern": False,
2535        "index": False,
2536        "ordinality": False,
2537    }
2538
2539    @property
2540    def name(self) -> str:
2541        if isinstance(self.this, Func):
2542            return ""
2543        return self.this.name
2544
2545    @property
2546    def db(self) -> str:
2547        return self.text("db")
2548
2549    @property
2550    def catalog(self) -> str:
2551        return self.text("catalog")
2552
2553    @property
2554    def selects(self) -> t.List[Expression]:
2555        return []
2556
2557    @property
2558    def named_selects(self) -> t.List[str]:
2559        return []
2560
2561    @property
2562    def parts(self) -> t.List[Expression]:
2563        """Return the parts of a table in order catalog, db, table."""
2564        parts: t.List[Expression] = []
2565
2566        for arg in ("catalog", "db", "this"):
2567            part = self.args.get(arg)
2568
2569            if isinstance(part, Dot):
2570                parts.extend(part.flatten())
2571            elif isinstance(part, Expression):
2572                parts.append(part)
2573
2574        return parts
arg_types = {'this': True, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'index': False, 'ordinality': False}
name: str
db: str
catalog: str
selects: List[Expression]
named_selects: List[str]
parts: List[Expression]

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

key = 'table'
class Union(Subqueryable):
2577class Union(Subqueryable):
2578    arg_types = {
2579        "with": False,
2580        "this": True,
2581        "expression": True,
2582        "distinct": False,
2583        "by_name": False,
2584        **QUERY_MODIFIERS,
2585    }
2586
2587    def limit(
2588        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2589    ) -> Select:
2590        """
2591        Set the LIMIT expression.
2592
2593        Example:
2594            >>> select("1").union(select("1")).limit(1).sql()
2595            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2596
2597        Args:
2598            expression: the SQL code string to parse.
2599                This can also be an integer.
2600                If a `Limit` instance is passed, this is used as-is.
2601                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2602            dialect: the dialect used to parse the input expression.
2603            copy: if `False`, modify this expression instance in-place.
2604            opts: other options to use to parse the input expressions.
2605
2606        Returns:
2607            The limited subqueryable.
2608        """
2609        return (
2610            select("*")
2611            .from_(self.subquery(alias="_l_0", copy=copy))
2612            .limit(expression, dialect=dialect, copy=False, **opts)
2613        )
2614
2615    def select(
2616        self,
2617        *expressions: t.Optional[ExpOrStr],
2618        append: bool = True,
2619        dialect: DialectType = None,
2620        copy: bool = True,
2621        **opts,
2622    ) -> Union:
2623        """Append to or set the SELECT of the union recursively.
2624
2625        Example:
2626            >>> from sqlglot import parse_one
2627            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2628            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2629
2630        Args:
2631            *expressions: the SQL code strings to parse.
2632                If an `Expression` instance is passed, it will be used as-is.
2633            append: if `True`, add to any existing expressions.
2634                Otherwise, this resets the expressions.
2635            dialect: the dialect used to parse the input expressions.
2636            copy: if `False`, modify this expression instance in-place.
2637            opts: other options to use to parse the input expressions.
2638
2639        Returns:
2640            Union: the modified expression.
2641        """
2642        this = self.copy() if copy else self
2643        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2644        this.expression.unnest().select(
2645            *expressions, append=append, dialect=dialect, copy=False, **opts
2646        )
2647        return this
2648
2649    @property
2650    def named_selects(self) -> t.List[str]:
2651        return self.this.unnest().named_selects
2652
2653    @property
2654    def is_star(self) -> bool:
2655        return self.this.is_star or self.expression.is_star
2656
2657    @property
2658    def selects(self) -> t.List[Expression]:
2659        return self.this.unnest().selects
2660
2661    @property
2662    def left(self) -> Expression:
2663        return self.this
2664
2665    @property
2666    def right(self) -> Expression:
2667        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:
2587    def limit(
2588        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2589    ) -> Select:
2590        """
2591        Set the LIMIT expression.
2592
2593        Example:
2594            >>> select("1").union(select("1")).limit(1).sql()
2595            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2596
2597        Args:
2598            expression: the SQL code string to parse.
2599                This can also be an integer.
2600                If a `Limit` instance is passed, this is used as-is.
2601                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2602            dialect: the dialect used to parse the input expression.
2603            copy: if `False`, modify this expression instance in-place.
2604            opts: other options to use to parse the input expressions.
2605
2606        Returns:
2607            The limited subqueryable.
2608        """
2609        return (
2610            select("*")
2611            .from_(self.subquery(alias="_l_0", copy=copy))
2612            .limit(expression, dialect=dialect, copy=False, **opts)
2613        )

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:
2615    def select(
2616        self,
2617        *expressions: t.Optional[ExpOrStr],
2618        append: bool = True,
2619        dialect: DialectType = None,
2620        copy: bool = True,
2621        **opts,
2622    ) -> Union:
2623        """Append to or set the SELECT of the union recursively.
2624
2625        Example:
2626            >>> from sqlglot import parse_one
2627            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2628            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2629
2630        Args:
2631            *expressions: the SQL code strings to parse.
2632                If an `Expression` instance is passed, it will be used as-is.
2633            append: if `True`, add to any existing expressions.
2634                Otherwise, this resets the expressions.
2635            dialect: the dialect used to parse the input expressions.
2636            copy: if `False`, modify this expression instance in-place.
2637            opts: other options to use to parse the input expressions.
2638
2639        Returns:
2640            Union: the modified expression.
2641        """
2642        this = self.copy() if copy else self
2643        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2644        this.expression.unnest().select(
2645            *expressions, append=append, dialect=dialect, copy=False, **opts
2646        )
2647        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]
is_star: bool

Checks whether an expression is a star.

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

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:
2775    def group_by(
2776        self,
2777        *expressions: t.Optional[ExpOrStr],
2778        append: bool = True,
2779        dialect: DialectType = None,
2780        copy: bool = True,
2781        **opts,
2782    ) -> Select:
2783        """
2784        Set the GROUP BY expression.
2785
2786        Example:
2787            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2788            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2789
2790        Args:
2791            *expressions: the SQL code strings to parse.
2792                If a `Group` instance is passed, this is used as-is.
2793                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2794                If nothing is passed in then a group by is not applied to the expression
2795            append: if `True`, add to any existing expressions.
2796                Otherwise, this flattens all the `Group` expression into a single expression.
2797            dialect: the dialect used to parse the input expression.
2798            copy: if `False`, modify this expression instance in-place.
2799            opts: other options to use to parse the input expressions.
2800
2801        Returns:
2802            The modified Select expression.
2803        """
2804        if not expressions:
2805            return self if not copy else self.copy()
2806
2807        return _apply_child_list_builder(
2808            *expressions,
2809            instance=self,
2810            arg="group",
2811            append=append,
2812            copy=copy,
2813            prefix="GROUP BY",
2814            into=Group,
2815            dialect=dialect,
2816            **opts,
2817        )

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:
2819    def order_by(
2820        self,
2821        *expressions: t.Optional[ExpOrStr],
2822        append: bool = True,
2823        dialect: DialectType = None,
2824        copy: bool = True,
2825        **opts,
2826    ) -> Select:
2827        """
2828        Set the ORDER BY expression.
2829
2830        Example:
2831            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2832            'SELECT x FROM tbl ORDER BY x DESC'
2833
2834        Args:
2835            *expressions: the SQL code strings to parse.
2836                If a `Group` instance is passed, this is used as-is.
2837                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2838            append: if `True`, add to any existing expressions.
2839                Otherwise, this flattens all the `Order` expression into a single expression.
2840            dialect: the dialect used to parse the input expression.
2841            copy: if `False`, modify this expression instance in-place.
2842            opts: other options to use to parse the input expressions.
2843
2844        Returns:
2845            The modified Select expression.
2846        """
2847        return _apply_child_list_builder(
2848            *expressions,
2849            instance=self,
2850            arg="order",
2851            append=append,
2852            copy=copy,
2853            prefix="ORDER BY",
2854            into=Order,
2855            dialect=dialect,
2856            **opts,
2857        )

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:
2859    def sort_by(
2860        self,
2861        *expressions: t.Optional[ExpOrStr],
2862        append: bool = True,
2863        dialect: DialectType = None,
2864        copy: bool = True,
2865        **opts,
2866    ) -> Select:
2867        """
2868        Set the SORT BY expression.
2869
2870        Example:
2871            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2872            'SELECT x FROM tbl SORT BY x DESC'
2873
2874        Args:
2875            *expressions: the SQL code strings to parse.
2876                If a `Group` instance is passed, this is used as-is.
2877                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2878            append: if `True`, add to any existing expressions.
2879                Otherwise, this flattens all the `Order` expression into a single expression.
2880            dialect: the dialect used to parse the input expression.
2881            copy: if `False`, modify this expression instance in-place.
2882            opts: other options to use to parse the input expressions.
2883
2884        Returns:
2885            The modified Select expression.
2886        """
2887        return _apply_child_list_builder(
2888            *expressions,
2889            instance=self,
2890            arg="sort",
2891            append=append,
2892            copy=copy,
2893            prefix="SORT BY",
2894            into=Sort,
2895            dialect=dialect,
2896            **opts,
2897        )

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

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:
2939    def limit(
2940        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2941    ) -> Select:
2942        """
2943        Set the LIMIT expression.
2944
2945        Example:
2946            >>> Select().from_("tbl").select("x").limit(10).sql()
2947            'SELECT x FROM tbl LIMIT 10'
2948
2949        Args:
2950            expression: the SQL code string to parse.
2951                This can also be an integer.
2952                If a `Limit` instance is passed, this is used as-is.
2953                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2954            dialect: the dialect used to parse the input expression.
2955            copy: if `False`, modify this expression instance in-place.
2956            opts: other options to use to parse the input expressions.
2957
2958        Returns:
2959            Select: the modified expression.
2960        """
2961        return _apply_builder(
2962            expression=expression,
2963            instance=self,
2964            arg="limit",
2965            into=Limit,
2966            prefix="LIMIT",
2967            dialect=dialect,
2968            copy=copy,
2969            into_arg="expression",
2970            **opts,
2971        )

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:
2973    def offset(
2974        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2975    ) -> Select:
2976        """
2977        Set the OFFSET expression.
2978
2979        Example:
2980            >>> Select().from_("tbl").select("x").offset(10).sql()
2981            'SELECT x FROM tbl OFFSET 10'
2982
2983        Args:
2984            expression: the SQL code string to parse.
2985                This can also be an integer.
2986                If a `Offset` instance is passed, this is used as-is.
2987                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
2988            dialect: the dialect used to parse the input expression.
2989            copy: if `False`, modify this expression instance in-place.
2990            opts: other options to use to parse the input expressions.
2991
2992        Returns:
2993            The modified Select expression.
2994        """
2995        return _apply_builder(
2996            expression=expression,
2997            instance=self,
2998            arg="offset",
2999            into=Offset,
3000            prefix="OFFSET",
3001            dialect=dialect,
3002            copy=copy,
3003            into_arg="expression",
3004            **opts,
3005        )

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:
3007    def select(
3008        self,
3009        *expressions: t.Optional[ExpOrStr],
3010        append: bool = True,
3011        dialect: DialectType = None,
3012        copy: bool = True,
3013        **opts,
3014    ) -> Select:
3015        """
3016        Append to or set the SELECT expressions.
3017
3018        Example:
3019            >>> Select().select("x", "y").sql()
3020            'SELECT x, y'
3021
3022        Args:
3023            *expressions: the SQL code strings to parse.
3024                If an `Expression` instance is passed, it will be used as-is.
3025            append: if `True`, add to any existing expressions.
3026                Otherwise, this resets the expressions.
3027            dialect: the dialect used to parse the input expressions.
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            The modified Select expression.
3033        """
3034        return _apply_list_builder(
3035            *expressions,
3036            instance=self,
3037            arg="expressions",
3038            append=append,
3039            dialect=dialect,
3040            copy=copy,
3041            **opts,
3042        )

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:
3044    def lateral(
3045        self,
3046        *expressions: t.Optional[ExpOrStr],
3047        append: bool = True,
3048        dialect: DialectType = None,
3049        copy: bool = True,
3050        **opts,
3051    ) -> Select:
3052        """
3053        Append to or set the LATERAL expressions.
3054
3055        Example:
3056            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3057            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3058
3059        Args:
3060            *expressions: the SQL code strings to parse.
3061                If an `Expression` instance is passed, it will be used as-is.
3062            append: if `True`, add to any existing expressions.
3063                Otherwise, this resets the expressions.
3064            dialect: the dialect used to parse the input expressions.
3065            copy: if `False`, modify this expression instance in-place.
3066            opts: other options to use to parse the input expressions.
3067
3068        Returns:
3069            The modified Select expression.
3070        """
3071        return _apply_list_builder(
3072            *expressions,
3073            instance=self,
3074            arg="laterals",
3075            append=append,
3076            into=Lateral,
3077            prefix="LATERAL VIEW",
3078            dialect=dialect,
3079            copy=copy,
3080            **opts,
3081        )

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:
3083    def join(
3084        self,
3085        expression: ExpOrStr,
3086        on: t.Optional[ExpOrStr] = None,
3087        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3088        append: bool = True,
3089        join_type: t.Optional[str] = None,
3090        join_alias: t.Optional[Identifier | str] = None,
3091        dialect: DialectType = None,
3092        copy: bool = True,
3093        **opts,
3094    ) -> Select:
3095        """
3096        Append to or set the JOIN expressions.
3097
3098        Example:
3099            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3100            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3101
3102            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3103            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3104
3105            Use `join_type` to change the type of join:
3106
3107            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3108            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3109
3110        Args:
3111            expression: the SQL code string to parse.
3112                If an `Expression` instance is passed, it will be used as-is.
3113            on: optionally specify the join "on" criteria as a SQL string.
3114                If an `Expression` instance is passed, it will be used as-is.
3115            using: optionally specify the join "using" criteria as a SQL string.
3116                If an `Expression` instance is passed, it will be used as-is.
3117            append: if `True`, add to any existing expressions.
3118                Otherwise, this resets the expressions.
3119            join_type: if set, alter the parsed join type.
3120            join_alias: an optional alias for the joined source.
3121            dialect: the dialect used to parse the input expressions.
3122            copy: if `False`, modify this expression instance in-place.
3123            opts: other options to use to parse the input expressions.
3124
3125        Returns:
3126            Select: the modified expression.
3127        """
3128        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3129
3130        try:
3131            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3132        except ParseError:
3133            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3134
3135        join = expression if isinstance(expression, Join) else Join(this=expression)
3136
3137        if isinstance(join.this, Select):
3138            join.this.replace(join.this.subquery())
3139
3140        if join_type:
3141            method: t.Optional[Token]
3142            side: t.Optional[Token]
3143            kind: t.Optional[Token]
3144
3145            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3146
3147            if method:
3148                join.set("method", method.text)
3149            if side:
3150                join.set("side", side.text)
3151            if kind:
3152                join.set("kind", kind.text)
3153
3154        if on:
3155            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3156            join.set("on", on)
3157
3158        if using:
3159            join = _apply_list_builder(
3160                *ensure_list(using),
3161                instance=join,
3162                arg="using",
3163                append=append,
3164                copy=copy,
3165                into=Identifier,
3166                **opts,
3167            )
3168
3169        if join_alias:
3170            join.set("this", alias_(join.this, join_alias, table=True))
3171
3172        return _apply_list_builder(
3173            join,
3174            instance=self,
3175            arg="joins",
3176            append=append,
3177            copy=copy,
3178            **opts,
3179        )

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:
3181    def where(
3182        self,
3183        *expressions: t.Optional[ExpOrStr],
3184        append: bool = True,
3185        dialect: DialectType = None,
3186        copy: bool = True,
3187        **opts,
3188    ) -> Select:
3189        """
3190        Append to or set the WHERE expressions.
3191
3192        Example:
3193            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3194            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3195
3196        Args:
3197            *expressions: the SQL code strings to parse.
3198                If an `Expression` instance is passed, it will be used as-is.
3199                Multiple expressions are combined with an AND operator.
3200            append: if `True`, AND the new expressions to any existing expression.
3201                Otherwise, this resets the expression.
3202            dialect: the dialect used to parse the input expressions.
3203            copy: if `False`, modify this expression instance in-place.
3204            opts: other options to use to parse the input expressions.
3205
3206        Returns:
3207            Select: the modified expression.
3208        """
3209        return _apply_conjunction_builder(
3210            *expressions,
3211            instance=self,
3212            arg="where",
3213            append=append,
3214            into=Where,
3215            dialect=dialect,
3216            copy=copy,
3217            **opts,
3218        )

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:
3220    def having(
3221        self,
3222        *expressions: t.Optional[ExpOrStr],
3223        append: bool = True,
3224        dialect: DialectType = None,
3225        copy: bool = True,
3226        **opts,
3227    ) -> Select:
3228        """
3229        Append to or set the HAVING expressions.
3230
3231        Example:
3232            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3233            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3234
3235        Args:
3236            *expressions: the SQL code strings to parse.
3237                If an `Expression` instance is passed, it will be used as-is.
3238                Multiple expressions are combined with an AND operator.
3239            append: if `True`, AND the new expressions to any existing expression.
3240                Otherwise, this resets the expression.
3241            dialect: the dialect used to parse the input expressions.
3242            copy: if `False`, modify this expression instance in-place.
3243            opts: other options to use to parse the input expressions.
3244
3245        Returns:
3246            The modified Select expression.
3247        """
3248        return _apply_conjunction_builder(
3249            *expressions,
3250            instance=self,
3251            arg="having",
3252            append=append,
3253            into=Having,
3254            dialect=dialect,
3255            copy=copy,
3256            **opts,
3257        )

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:
3259    def window(
3260        self,
3261        *expressions: t.Optional[ExpOrStr],
3262        append: bool = True,
3263        dialect: DialectType = None,
3264        copy: bool = True,
3265        **opts,
3266    ) -> Select:
3267        return _apply_list_builder(
3268            *expressions,
3269            instance=self,
3270            arg="windows",
3271            append=append,
3272            into=Window,
3273            dialect=dialect,
3274            copy=copy,
3275            **opts,
3276        )
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:
3278    def qualify(
3279        self,
3280        *expressions: t.Optional[ExpOrStr],
3281        append: bool = True,
3282        dialect: DialectType = None,
3283        copy: bool = True,
3284        **opts,
3285    ) -> Select:
3286        return _apply_conjunction_builder(
3287            *expressions,
3288            instance=self,
3289            arg="qualify",
3290            append=append,
3291            into=Qualify,
3292            dialect=dialect,
3293            copy=copy,
3294            **opts,
3295        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3297    def distinct(
3298        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3299    ) -> Select:
3300        """
3301        Set the OFFSET expression.
3302
3303        Example:
3304            >>> Select().from_("tbl").select("x").distinct().sql()
3305            'SELECT DISTINCT x FROM tbl'
3306
3307        Args:
3308            ons: the expressions to distinct on
3309            distinct: whether the Select should be distinct
3310            copy: if `False`, modify this expression instance in-place.
3311
3312        Returns:
3313            Select: the modified expression.
3314        """
3315        instance = maybe_copy(self, copy)
3316        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3317        instance.set("distinct", Distinct(on=on) if distinct else None)
3318        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:
3320    def ctas(
3321        self,
3322        table: ExpOrStr,
3323        properties: t.Optional[t.Dict] = None,
3324        dialect: DialectType = None,
3325        copy: bool = True,
3326        **opts,
3327    ) -> Create:
3328        """
3329        Convert this expression to a CREATE TABLE AS statement.
3330
3331        Example:
3332            >>> Select().select("*").from_("tbl").ctas("x").sql()
3333            'CREATE TABLE x AS SELECT * FROM tbl'
3334
3335        Args:
3336            table: the SQL code string to parse as the table name.
3337                If another `Expression` instance is passed, it will be used as-is.
3338            properties: an optional mapping of table properties
3339            dialect: the dialect used to parse the input table.
3340            copy: if `False`, modify this expression instance in-place.
3341            opts: other options to use to parse the input table.
3342
3343        Returns:
3344            The new Create expression.
3345        """
3346        instance = maybe_copy(self, copy)
3347        table_expression = maybe_parse(
3348            table,
3349            into=Table,
3350            dialect=dialect,
3351            **opts,
3352        )
3353        properties_expression = None
3354        if properties:
3355            properties_expression = Properties.from_dict(properties)
3356
3357        return Create(
3358            this=table_expression,
3359            kind="table",
3360            expression=instance,
3361            properties=properties_expression,
3362        )

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:
3364    def lock(self, update: bool = True, copy: bool = True) -> Select:
3365        """
3366        Set the locking read mode for this expression.
3367
3368        Examples:
3369            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3370            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3371
3372            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3373            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3374
3375        Args:
3376            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3377            copy: if `False`, modify this expression instance in-place.
3378
3379        Returns:
3380            The modified expression.
3381        """
3382        inst = maybe_copy(self, copy)
3383        inst.set("locks", [Lock(update=update)])
3384
3385        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:
3387    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3388        """
3389        Set hints for this expression.
3390
3391        Examples:
3392            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3393            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3394
3395        Args:
3396            hints: The SQL code strings to parse as the hints.
3397                If an `Expression` instance is passed, it will be used as-is.
3398            dialect: The dialect used to parse the hints.
3399            copy: If `False`, modify this expression instance in-place.
3400
3401        Returns:
3402            The modified expression.
3403        """
3404        inst = maybe_copy(self, copy)
3405        inst.set(
3406            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3407        )
3408
3409        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]
is_star: bool

Checks whether an expression is a star.

selects: List[Expression]
key = 'select'
class Subquery(DerivedTable, Unionable):
3424class Subquery(DerivedTable, Unionable):
3425    arg_types = {
3426        "this": True,
3427        "alias": False,
3428        "with": False,
3429        **QUERY_MODIFIERS,
3430    }
3431
3432    def unnest(self):
3433        """
3434        Returns the first non subquery.
3435        """
3436        expression = self
3437        while isinstance(expression, Subquery):
3438            expression = expression.this
3439        return expression
3440
3441    def unwrap(self) -> Subquery:
3442        expression = self
3443        while expression.same_parent and expression.is_wrapper:
3444            expression = t.cast(Subquery, expression.parent)
3445        return expression
3446
3447    @property
3448    def is_wrapper(self) -> bool:
3449        """
3450        Whether this Subquery acts as a simple wrapper around another expression.
3451
3452        SELECT * FROM (((SELECT * FROM t)))
3453                      ^
3454                      This corresponds to a "wrapper" Subquery node
3455        """
3456        return all(v is None for k, v in self.args.items() if k != "this")
3457
3458    @property
3459    def is_star(self) -> bool:
3460        return self.this.is_star
3461
3462    @property
3463    def output_name(self) -> str:
3464        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):
3432    def unnest(self):
3433        """
3434        Returns the first non subquery.
3435        """
3436        expression = self
3437        while isinstance(expression, Subquery):
3438            expression = expression.this
3439        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3441    def unwrap(self) -> Subquery:
3442        expression = self
3443        while expression.same_parent and expression.is_wrapper:
3444            expression = t.cast(Subquery, expression.parent)
3445        return expression
is_wrapper: bool

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

Checks whether an expression is a star.

output_name: str

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):
3467class TableSample(Expression):
3468    arg_types = {
3469        "this": False,
3470        "expressions": False,
3471        "method": False,
3472        "bucket_numerator": False,
3473        "bucket_denominator": False,
3474        "bucket_field": False,
3475        "percent": False,
3476        "rows": False,
3477        "size": False,
3478        "seed": False,
3479        "kind": False,
3480    }
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, 'kind': False}
key = 'tablesample'
class Tag(Expression):
3483class Tag(Expression):
3484    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3485
3486    arg_types = {
3487        "this": False,
3488        "prefix": False,
3489        "postfix": False,
3490    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3495class Pivot(Expression):
3496    arg_types = {
3497        "this": False,
3498        "alias": False,
3499        "expressions": False,
3500        "field": False,
3501        "unpivot": False,
3502        "using": False,
3503        "group": False,
3504        "columns": False,
3505        "include_nulls": False,
3506    }
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
key = 'pivot'
class Window(Condition):
3509class Window(Condition):
3510    arg_types = {
3511        "this": True,
3512        "partition_by": False,
3513        "order": False,
3514        "spec": False,
3515        "alias": False,
3516        "over": False,
3517        "first": False,
3518    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3521class WindowSpec(Expression):
3522    arg_types = {
3523        "kind": False,
3524        "start": False,
3525        "start_side": False,
3526        "end": False,
3527        "end_side": False,
3528    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3531class Where(Expression):
3532    pass
key = 'where'
class Star(Expression):
3535class Star(Expression):
3536    arg_types = {"except": False, "replace": False}
3537
3538    @property
3539    def name(self) -> str:
3540        return "*"
3541
3542    @property
3543    def output_name(self) -> str:
3544        return self.name
arg_types = {'except': False, 'replace': False}
name: str
output_name: str

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):
3547class Parameter(Condition):
3548    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3551class SessionParameter(Condition):
3552    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3555class Placeholder(Condition):
3556    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3559class Null(Condition):
3560    arg_types: t.Dict[str, t.Any] = {}
3561
3562    @property
3563    def name(self) -> str:
3564        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
key = 'null'
class Boolean(Condition):
3567class Boolean(Condition):
3568    pass
key = 'boolean'
class DataTypeParam(Expression):
3571class DataTypeParam(Expression):
3572    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3575class DataType(Expression):
3576    arg_types = {
3577        "this": True,
3578        "expressions": False,
3579        "nested": False,
3580        "values": False,
3581        "prefix": False,
3582        "kind": False,
3583    }
3584
3585    class Type(AutoName):
3586        ARRAY = auto()
3587        BIGDECIMAL = auto()
3588        BIGINT = auto()
3589        BIGSERIAL = auto()
3590        BINARY = auto()
3591        BIT = auto()
3592        BOOLEAN = auto()
3593        CHAR = auto()
3594        DATE = auto()
3595        DATEMULTIRANGE = auto()
3596        DATERANGE = auto()
3597        DATETIME = auto()
3598        DATETIME64 = auto()
3599        DECIMAL = auto()
3600        DOUBLE = auto()
3601        ENUM = auto()
3602        ENUM8 = auto()
3603        ENUM16 = auto()
3604        FIXEDSTRING = auto()
3605        FLOAT = auto()
3606        GEOGRAPHY = auto()
3607        GEOMETRY = auto()
3608        HLLSKETCH = auto()
3609        HSTORE = auto()
3610        IMAGE = auto()
3611        INET = auto()
3612        INT = auto()
3613        INT128 = auto()
3614        INT256 = auto()
3615        INT4MULTIRANGE = auto()
3616        INT4RANGE = auto()
3617        INT8MULTIRANGE = auto()
3618        INT8RANGE = auto()
3619        INTERVAL = auto()
3620        IPADDRESS = auto()
3621        IPPREFIX = auto()
3622        JSON = auto()
3623        JSONB = auto()
3624        LONGBLOB = auto()
3625        LONGTEXT = auto()
3626        LOWCARDINALITY = auto()
3627        MAP = auto()
3628        MEDIUMBLOB = auto()
3629        MEDIUMINT = auto()
3630        MEDIUMTEXT = auto()
3631        MONEY = auto()
3632        NCHAR = auto()
3633        NESTED = auto()
3634        NULL = auto()
3635        NULLABLE = auto()
3636        NUMMULTIRANGE = auto()
3637        NUMRANGE = auto()
3638        NVARCHAR = auto()
3639        OBJECT = auto()
3640        ROWVERSION = auto()
3641        SERIAL = auto()
3642        SET = auto()
3643        SMALLINT = auto()
3644        SMALLMONEY = auto()
3645        SMALLSERIAL = auto()
3646        STRUCT = auto()
3647        SUPER = auto()
3648        TEXT = auto()
3649        TINYBLOB = auto()
3650        TINYTEXT = auto()
3651        TIME = auto()
3652        TIMETZ = auto()
3653        TIMESTAMP = auto()
3654        TIMESTAMPLTZ = auto()
3655        TIMESTAMPTZ = auto()
3656        TIMESTAMP_S = auto()
3657        TIMESTAMP_MS = auto()
3658        TIMESTAMP_NS = auto()
3659        TINYINT = auto()
3660        TSMULTIRANGE = auto()
3661        TSRANGE = auto()
3662        TSTZMULTIRANGE = auto()
3663        TSTZRANGE = auto()
3664        UBIGINT = auto()
3665        UINT = auto()
3666        UINT128 = auto()
3667        UINT256 = auto()
3668        UMEDIUMINT = auto()
3669        UDECIMAL = auto()
3670        UNIQUEIDENTIFIER = auto()
3671        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3672        USERDEFINED = "USER-DEFINED"
3673        USMALLINT = auto()
3674        UTINYINT = auto()
3675        UUID = auto()
3676        VARBINARY = auto()
3677        VARCHAR = auto()
3678        VARIANT = auto()
3679        XML = auto()
3680        YEAR = auto()
3681
3682    TEXT_TYPES = {
3683        Type.CHAR,
3684        Type.NCHAR,
3685        Type.VARCHAR,
3686        Type.NVARCHAR,
3687        Type.TEXT,
3688    }
3689
3690    INTEGER_TYPES = {
3691        Type.INT,
3692        Type.TINYINT,
3693        Type.SMALLINT,
3694        Type.BIGINT,
3695        Type.INT128,
3696        Type.INT256,
3697        Type.BIT,
3698    }
3699
3700    FLOAT_TYPES = {
3701        Type.FLOAT,
3702        Type.DOUBLE,
3703    }
3704
3705    NUMERIC_TYPES = {
3706        *INTEGER_TYPES,
3707        *FLOAT_TYPES,
3708    }
3709
3710    TEMPORAL_TYPES = {
3711        Type.TIME,
3712        Type.TIMETZ,
3713        Type.TIMESTAMP,
3714        Type.TIMESTAMPTZ,
3715        Type.TIMESTAMPLTZ,
3716        Type.TIMESTAMP_S,
3717        Type.TIMESTAMP_MS,
3718        Type.TIMESTAMP_NS,
3719        Type.DATE,
3720        Type.DATETIME,
3721        Type.DATETIME64,
3722    }
3723
3724    @classmethod
3725    def build(
3726        cls,
3727        dtype: DATA_TYPE,
3728        dialect: DialectType = None,
3729        udt: bool = False,
3730        **kwargs,
3731    ) -> DataType:
3732        """
3733        Constructs a DataType object.
3734
3735        Args:
3736            dtype: the data type of interest.
3737            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3738            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3739                DataType, thus creating a user-defined type.
3740            kawrgs: additional arguments to pass in the constructor of DataType.
3741
3742        Returns:
3743            The constructed DataType object.
3744        """
3745        from sqlglot import parse_one
3746
3747        if isinstance(dtype, str):
3748            if dtype.upper() == "UNKNOWN":
3749                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3750
3751            try:
3752                data_type_exp = parse_one(
3753                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3754                )
3755            except ParseError:
3756                if udt:
3757                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3758                raise
3759        elif isinstance(dtype, DataType.Type):
3760            data_type_exp = DataType(this=dtype)
3761        elif isinstance(dtype, DataType):
3762            return dtype
3763        else:
3764            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3765
3766        return DataType(**{**data_type_exp.args, **kwargs})
3767
3768    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3769        """
3770        Checks whether this DataType matches one of the provided data types. Nested types or precision
3771        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3772
3773        Args:
3774            dtypes: the data types to compare this DataType to.
3775
3776        Returns:
3777            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3778        """
3779        for dtype in dtypes:
3780            other = DataType.build(dtype, udt=True)
3781
3782            if (
3783                other.expressions
3784                or self.this == DataType.Type.USERDEFINED
3785                or other.this == DataType.Type.USERDEFINED
3786            ):
3787                matches = self == other
3788            else:
3789                matches = self.this == other.this
3790
3791            if matches:
3792                return True
3793        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>}
INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>}
TEMPORAL_TYPES = {<Type.TIMETZ: 'TIMETZ'>, <Type.TIME: 'TIME'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE: 'DATE'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, **kwargs) -> DataType:
3724    @classmethod
3725    def build(
3726        cls,
3727        dtype: DATA_TYPE,
3728        dialect: DialectType = None,
3729        udt: bool = False,
3730        **kwargs,
3731    ) -> DataType:
3732        """
3733        Constructs a DataType object.
3734
3735        Args:
3736            dtype: the data type of interest.
3737            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3738            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3739                DataType, thus creating a user-defined type.
3740            kawrgs: additional arguments to pass in the constructor of DataType.
3741
3742        Returns:
3743            The constructed DataType object.
3744        """
3745        from sqlglot import parse_one
3746
3747        if isinstance(dtype, str):
3748            if dtype.upper() == "UNKNOWN":
3749                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3750
3751            try:
3752                data_type_exp = parse_one(
3753                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3754                )
3755            except ParseError:
3756                if udt:
3757                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3758                raise
3759        elif isinstance(dtype, DataType.Type):
3760            data_type_exp = DataType(this=dtype)
3761        elif isinstance(dtype, DataType):
3762            return dtype
3763        else:
3764            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3765
3766        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.
  • kawrgs: 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:
3768    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3769        """
3770        Checks whether this DataType matches one of the provided data types. Nested types or precision
3771        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3772
3773        Args:
3774            dtypes: the data types to compare this DataType to.
3775
3776        Returns:
3777            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3778        """
3779        for dtype in dtypes:
3780            other = DataType.build(dtype, udt=True)
3781
3782            if (
3783                other.expressions
3784                or self.this == DataType.Type.USERDEFINED
3785                or other.this == DataType.Type.USERDEFINED
3786            ):
3787                matches = self == other
3788            else:
3789                matches = self.this == other.this
3790
3791            if matches:
3792                return True
3793        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):
3585    class Type(AutoName):
3586        ARRAY = auto()
3587        BIGDECIMAL = auto()
3588        BIGINT = auto()
3589        BIGSERIAL = auto()
3590        BINARY = auto()
3591        BIT = auto()
3592        BOOLEAN = auto()
3593        CHAR = auto()
3594        DATE = auto()
3595        DATEMULTIRANGE = auto()
3596        DATERANGE = auto()
3597        DATETIME = auto()
3598        DATETIME64 = auto()
3599        DECIMAL = auto()
3600        DOUBLE = auto()
3601        ENUM = auto()
3602        ENUM8 = auto()
3603        ENUM16 = auto()
3604        FIXEDSTRING = auto()
3605        FLOAT = auto()
3606        GEOGRAPHY = auto()
3607        GEOMETRY = auto()
3608        HLLSKETCH = auto()
3609        HSTORE = auto()
3610        IMAGE = auto()
3611        INET = auto()
3612        INT = auto()
3613        INT128 = auto()
3614        INT256 = auto()
3615        INT4MULTIRANGE = auto()
3616        INT4RANGE = auto()
3617        INT8MULTIRANGE = auto()
3618        INT8RANGE = auto()
3619        INTERVAL = auto()
3620        IPADDRESS = auto()
3621        IPPREFIX = auto()
3622        JSON = auto()
3623        JSONB = auto()
3624        LONGBLOB = auto()
3625        LONGTEXT = auto()
3626        LOWCARDINALITY = auto()
3627        MAP = auto()
3628        MEDIUMBLOB = auto()
3629        MEDIUMINT = auto()
3630        MEDIUMTEXT = auto()
3631        MONEY = auto()
3632        NCHAR = auto()
3633        NESTED = auto()
3634        NULL = auto()
3635        NULLABLE = auto()
3636        NUMMULTIRANGE = auto()
3637        NUMRANGE = auto()
3638        NVARCHAR = auto()
3639        OBJECT = auto()
3640        ROWVERSION = auto()
3641        SERIAL = auto()
3642        SET = auto()
3643        SMALLINT = auto()
3644        SMALLMONEY = auto()
3645        SMALLSERIAL = auto()
3646        STRUCT = auto()
3647        SUPER = auto()
3648        TEXT = auto()
3649        TINYBLOB = auto()
3650        TINYTEXT = auto()
3651        TIME = auto()
3652        TIMETZ = auto()
3653        TIMESTAMP = auto()
3654        TIMESTAMPLTZ = auto()
3655        TIMESTAMPTZ = auto()
3656        TIMESTAMP_S = auto()
3657        TIMESTAMP_MS = auto()
3658        TIMESTAMP_NS = auto()
3659        TINYINT = auto()
3660        TSMULTIRANGE = auto()
3661        TSRANGE = auto()
3662        TSTZMULTIRANGE = auto()
3663        TSTZRANGE = auto()
3664        UBIGINT = auto()
3665        UINT = auto()
3666        UINT128 = auto()
3667        UINT256 = auto()
3668        UMEDIUMINT = auto()
3669        UDECIMAL = auto()
3670        UNIQUEIDENTIFIER = auto()
3671        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3672        USERDEFINED = "USER-DEFINED"
3673        USMALLINT = auto()
3674        UTINYINT = auto()
3675        UUID = auto()
3676        VARBINARY = auto()
3677        VARCHAR = auto()
3678        VARIANT = auto()
3679        XML = auto()
3680        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
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'>
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):
3800class PseudoType(DataType):
3801    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3805class ObjectIdentifier(DataType):
3806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3810class SubqueryPredicate(Predicate):
3811    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3814class All(SubqueryPredicate):
3815    pass
key = 'all'
class Any(SubqueryPredicate):
3818class Any(SubqueryPredicate):
3819    pass
key = 'any'
class Exists(SubqueryPredicate):
3822class Exists(SubqueryPredicate):
3823    pass
key = 'exists'
class Command(Expression):
3828class Command(Expression):
3829    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3832class Transaction(Expression):
3833    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3836class Commit(Expression):
3837    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3840class Rollback(Expression):
3841    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3844class AlterTable(Expression):
3845    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):
3848class AddConstraint(Expression):
3849    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3852class DropPartition(Expression):
3853    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3857class Binary(Condition):
3858    arg_types = {"this": True, "expression": True}
3859
3860    @property
3861    def left(self) -> Expression:
3862        return self.this
3863
3864    @property
3865    def right(self) -> Expression:
3866        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
right: Expression
key = 'binary'
class Add(Binary):
3869class Add(Binary):
3870    pass
key = 'add'
class Connector(Binary):
3873class Connector(Binary):
3874    pass
key = 'connector'
class And(Connector):
3877class And(Connector):
3878    pass
key = 'and'
class Or(Connector):
3881class Or(Connector):
3882    pass
key = 'or'
class BitwiseAnd(Binary):
3885class BitwiseAnd(Binary):
3886    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3889class BitwiseLeftShift(Binary):
3890    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3893class BitwiseOr(Binary):
3894    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3897class BitwiseRightShift(Binary):
3898    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3901class BitwiseXor(Binary):
3902    pass
key = 'bitwisexor'
class Div(Binary):
3905class Div(Binary):
3906    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):
3909class Overlaps(Binary):
3910    pass
key = 'overlaps'
class Dot(Binary):
3913class Dot(Binary):
3914    @property
3915    def name(self) -> str:
3916        return self.expression.name
3917
3918    @property
3919    def output_name(self) -> str:
3920        return self.name
3921
3922    @classmethod
3923    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3924        """Build a Dot object with a sequence of expressions."""
3925        if len(expressions) < 2:
3926            raise ValueError(f"Dot requires >= 2 expressions.")
3927
3928        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
3929
3930    @property
3931    def parts(self) -> t.List[Expression]:
3932        """Return the parts of a table / column in order catalog, db, table."""
3933        this, *parts = self.flatten()
3934
3935        parts.reverse()
3936
3937        for arg in ("this", "table", "db", "catalog"):
3938            part = this.args.get(arg)
3939
3940            if isinstance(part, Expression):
3941                parts.append(part)
3942
3943        parts.reverse()
3944        return parts
name: str
output_name: str

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:
3922    @classmethod
3923    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3924        """Build a Dot object with a sequence of expressions."""
3925        if len(expressions) < 2:
3926            raise ValueError(f"Dot requires >= 2 expressions.")
3927
3928        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]

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

key = 'dot'
class DPipe(Binary):
3947class DPipe(Binary):
3948    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
3951class EQ(Binary, Predicate):
3952    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3955class NullSafeEQ(Binary, Predicate):
3956    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3959class NullSafeNEQ(Binary, Predicate):
3960    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3964class PropertyEQ(Binary):
3965    pass
key = 'propertyeq'
class Distance(Binary):
3968class Distance(Binary):
3969    pass
key = 'distance'
class Escape(Binary):
3972class Escape(Binary):
3973    pass
key = 'escape'
class Glob(Binary, Predicate):
3976class Glob(Binary, Predicate):
3977    pass
key = 'glob'
class GT(Binary, Predicate):
3980class GT(Binary, Predicate):
3981    pass
key = 'gt'
class GTE(Binary, Predicate):
3984class GTE(Binary, Predicate):
3985    pass
key = 'gte'
class ILike(Binary, Predicate):
3988class ILike(Binary, Predicate):
3989    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3992class ILikeAny(Binary, Predicate):
3993    pass
key = 'ilikeany'
class IntDiv(Binary):
3996class IntDiv(Binary):
3997    pass
key = 'intdiv'
class Is(Binary, Predicate):
4000class Is(Binary, Predicate):
4001    pass
key = 'is'
class Kwarg(Binary):
4004class Kwarg(Binary):
4005    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4008class Like(Binary, Predicate):
4009    pass
key = 'like'
class LikeAny(Binary, Predicate):
4012class LikeAny(Binary, Predicate):
4013    pass
key = 'likeany'
class LT(Binary, Predicate):
4016class LT(Binary, Predicate):
4017    pass
key = 'lt'
class LTE(Binary, Predicate):
4020class LTE(Binary, Predicate):
4021    pass
key = 'lte'
class Mod(Binary):
4024class Mod(Binary):
4025    pass
key = 'mod'
class Mul(Binary):
4028class Mul(Binary):
4029    pass
key = 'mul'
class NEQ(Binary, Predicate):
4032class NEQ(Binary, Predicate):
4033    pass
key = 'neq'
class Operator(Binary):
4037class Operator(Binary):
4038    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4041class SimilarTo(Binary, Predicate):
4042    pass
key = 'similarto'
class Slice(Binary):
4045class Slice(Binary):
4046    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4049class Sub(Binary):
4050    pass
key = 'sub'
class ArrayOverlaps(Binary):
4053class ArrayOverlaps(Binary):
4054    pass
key = 'arrayoverlaps'
class Unary(Condition):
4059class Unary(Condition):
4060    pass
key = 'unary'
class BitwiseNot(Unary):
4063class BitwiseNot(Unary):
4064    pass
key = 'bitwisenot'
class Not(Unary):
4067class Not(Unary):
4068    pass
key = 'not'
class Paren(Unary):
4071class Paren(Unary):
4072    arg_types = {"this": True, "with": False}
4073
4074    @property
4075    def output_name(self) -> str:
4076        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str

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):
4079class Neg(Unary):
4080    pass
key = 'neg'
class Alias(Expression):
4083class Alias(Expression):
4084    arg_types = {"this": True, "alias": False}
4085
4086    @property
4087    def output_name(self) -> str:
4088        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str

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 Aliases(Expression):
4091class Aliases(Expression):
4092    arg_types = {"this": True, "expressions": True}
4093
4094    @property
4095    def aliases(self):
4096        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
4099class AtTimeZone(Expression):
4100    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4103class Between(Predicate):
4104    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4107class Bracket(Condition):
4108    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4109    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4110
4111    @property
4112    def output_name(self) -> str:
4113        if len(self.expressions) == 1:
4114            return self.expressions[0].output_name
4115
4116        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str

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):
4119class Distinct(Expression):
4120    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4123class In(Predicate):
4124    arg_types = {
4125        "this": True,
4126        "expressions": False,
4127        "query": False,
4128        "unnest": False,
4129        "field": False,
4130        "is_global": False,
4131    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4135class ForIn(Expression):
4136    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4139class TimeUnit(Expression):
4140    """Automatically converts unit arg into a var."""
4141
4142    arg_types = {"unit": False}
4143
4144    UNABBREVIATED_UNIT_NAME = {
4145        "d": "day",
4146        "h": "hour",
4147        "m": "minute",
4148        "ms": "millisecond",
4149        "ns": "nanosecond",
4150        "q": "quarter",
4151        "s": "second",
4152        "us": "microsecond",
4153        "w": "week",
4154        "y": "year",
4155    }
4156
4157    VAR_LIKE = (Column, Literal, Var)
4158
4159    def __init__(self, **args):
4160        unit = args.get("unit")
4161        if isinstance(unit, self.VAR_LIKE):
4162            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4163        elif isinstance(unit, Week):
4164            unit.set("this", Var(this=unit.this.name))
4165
4166        super().__init__(**args)
4167
4168    @property
4169    def unit(self) -> t.Optional[Var]:
4170        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4159    def __init__(self, **args):
4160        unit = args.get("unit")
4161        if isinstance(unit, self.VAR_LIKE):
4162            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4163        elif isinstance(unit, Week):
4164            unit.set("this", Var(this=unit.this.name))
4165
4166        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]
key = 'timeunit'
class IntervalOp(TimeUnit):
4173class IntervalOp(TimeUnit):
4174    arg_types = {"unit": True, "expression": True}
4175
4176    def interval(self):
4177        return Interval(
4178            this=self.expression.copy(),
4179            unit=self.unit.copy(),
4180        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4176    def interval(self):
4177        return Interval(
4178            this=self.expression.copy(),
4179            unit=self.unit.copy(),
4180        )
key = 'intervalop'
class IntervalSpan(DataType):
4186class IntervalSpan(DataType):
4187    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4190class Interval(TimeUnit):
4191    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4194class IgnoreNulls(Expression):
4195    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4198class RespectNulls(Expression):
4199    pass
key = 'respectnulls'
class Func(Condition):
4203class Func(Condition):
4204    """
4205    The base class for all function expressions.
4206
4207    Attributes:
4208        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4209            treated as a variable length argument and the argument's value will be stored as a list.
4210        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4211            for this function expression. These values are used to map this node to a name during parsing
4212            as well as to provide the function's name during SQL string generation. By default the SQL
4213            name is set to the expression's class name transformed to snake case.
4214    """
4215
4216    is_var_len_args = False
4217
4218    @classmethod
4219    def from_arg_list(cls, args):
4220        if cls.is_var_len_args:
4221            all_arg_keys = list(cls.arg_types)
4222            # If this function supports variable length argument treat the last argument as such.
4223            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4224            num_non_var = len(non_var_len_arg_keys)
4225
4226            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4227            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4228        else:
4229            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4230
4231        return cls(**args_dict)
4232
4233    @classmethod
4234    def sql_names(cls):
4235        if cls is Func:
4236            raise NotImplementedError(
4237                "SQL name is only supported by concrete function implementations"
4238            )
4239        if "_sql_names" not in cls.__dict__:
4240            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4241        return cls._sql_names
4242
4243    @classmethod
4244    def sql_name(cls):
4245        return cls.sql_names()[0]
4246
4247    @classmethod
4248    def default_parser_mappings(cls):
4249        return {name: cls.from_arg_list for name in cls.sql_names()}

The base class for all function expressions.

Attributes:
  • is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
  • _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
is_var_len_args = False
@classmethod
def from_arg_list(cls, args):
4218    @classmethod
4219    def from_arg_list(cls, args):
4220        if cls.is_var_len_args:
4221            all_arg_keys = list(cls.arg_types)
4222            # If this function supports variable length argument treat the last argument as such.
4223            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4224            num_non_var = len(non_var_len_arg_keys)
4225
4226            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4227            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4228        else:
4229            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4230
4231        return cls(**args_dict)
@classmethod
def sql_names(cls):
4233    @classmethod
4234    def sql_names(cls):
4235        if cls is Func:
4236            raise NotImplementedError(
4237                "SQL name is only supported by concrete function implementations"
4238            )
4239        if "_sql_names" not in cls.__dict__:
4240            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4241        return cls._sql_names
@classmethod
def sql_name(cls):
4243    @classmethod
4244    def sql_name(cls):
4245        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4247    @classmethod
4248    def default_parser_mappings(cls):
4249        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4252class AggFunc(Func):
4253    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4256class ParameterizedAgg(AggFunc):
4257    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4260class Abs(Func):
4261    pass
key = 'abs'
class ArgMax(AggFunc):
4264class ArgMax(AggFunc):
4265    arg_types = {"this": True, "expression": True, "count": False}
4266    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4269class ArgMin(AggFunc):
4270    arg_types = {"this": True, "expression": True, "count": False}
4271    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4274class ApproxTopK(AggFunc):
4275    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4278class Flatten(Func):
4279    pass
key = 'flatten'
class Transform(Func):
4283class Transform(Func):
4284    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4287class Anonymous(Func):
4288    arg_types = {"this": True, "expressions": False}
4289    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4294class Hll(AggFunc):
4295    arg_types = {"this": True, "expressions": False}
4296    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4299class ApproxDistinct(AggFunc):
4300    arg_types = {"this": True, "accuracy": False}
4301    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4304class Array(Func):
4305    arg_types = {"expressions": False}
4306    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4311class ToChar(Func):
4312    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4315class GenerateSeries(Func):
4316    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4319class ArrayAgg(AggFunc):
4320    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4323class ArrayUniqueAgg(AggFunc):
4324    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4327class ArrayAll(Func):
4328    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4331class ArrayAny(Func):
4332    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4335class ArrayConcat(Func):
4336    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4337    arg_types = {"this": True, "expressions": False}
4338    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4341class ArrayContains(Binary, Func):
4342    pass
key = 'arraycontains'
class ArrayContained(Binary):
4345class ArrayContained(Binary):
4346    pass
key = 'arraycontained'
class ArrayFilter(Func):
4349class ArrayFilter(Func):
4350    arg_types = {"this": True, "expression": True}
4351    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4354class ArrayJoin(Func):
4355    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4358class ArraySize(Func):
4359    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4362class ArraySort(Func):
4363    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4366class ArraySum(Func):
4367    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4370class ArrayUnionAgg(AggFunc):
4371    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4374class Avg(AggFunc):
4375    pass
key = 'avg'
class AnyValue(AggFunc):
4378class AnyValue(AggFunc):
4379    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
arg_types = {'this': True, 'having': False, 'max': False, 'ignore_nulls': False}
key = 'anyvalue'
class First(Func):
4382class First(Func):
4383    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4386class Last(Func):
4387    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4390class Case(Func):
4391    arg_types = {"this": False, "ifs": True, "default": False}
4392
4393    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4394        instance = maybe_copy(self, copy)
4395        instance.append(
4396            "ifs",
4397            If(
4398                this=maybe_parse(condition, copy=copy, **opts),
4399                true=maybe_parse(then, copy=copy, **opts),
4400            ),
4401        )
4402        return instance
4403
4404    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4405        instance = maybe_copy(self, copy)
4406        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4407        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:
4393    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4394        instance = maybe_copy(self, copy)
4395        instance.append(
4396            "ifs",
4397            If(
4398                this=maybe_parse(condition, copy=copy, **opts),
4399                true=maybe_parse(then, copy=copy, **opts),
4400            ),
4401        )
4402        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4404    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4405        instance = maybe_copy(self, copy)
4406        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4407        return instance
key = 'case'
class Cast(Func):
4410class Cast(Func):
4411    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4412
4413    @property
4414    def name(self) -> str:
4415        return self.this.name
4416
4417    @property
4418    def to(self) -> DataType:
4419        return self.args["to"]
4420
4421    @property
4422    def output_name(self) -> str:
4423        return self.name
4424
4425    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4426        """
4427        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4428        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4429        array<int> != array<float>.
4430
4431        Args:
4432            dtypes: the data types to compare this Cast's DataType to.
4433
4434        Returns:
4435            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4436        """
4437        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
to: DataType
output_name: str

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:
4425    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4426        """
4427        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4428        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4429        array<int> != array<float>.
4430
4431        Args:
4432            dtypes: the data types to compare this Cast's DataType to.
4433
4434        Returns:
4435            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4436        """
4437        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):
4440class TryCast(Cast):
4441    pass
key = 'trycast'
class CastToStrType(Func):
4444class CastToStrType(Func):
4445    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4448class Collate(Binary, Func):
4449    pass
key = 'collate'
class Ceil(Func):
4452class Ceil(Func):
4453    arg_types = {"this": True, "decimals": False}
4454    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4457class Coalesce(Func):
4458    arg_types = {"this": True, "expressions": False}
4459    is_var_len_args = True
4460    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4463class Chr(Func):
4464    arg_types = {"this": True, "charset": False, "expressions": False}
4465    is_var_len_args = True
4466    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4469class Concat(Func):
4470    arg_types = {"expressions": True, "safe": False}
4471    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4474class ConcatWs(Concat):
4475    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4478class Count(AggFunc):
4479    arg_types = {"this": False, "expressions": False}
4480    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4483class CountIf(AggFunc):
4484    pass
key = 'countif'
class CurrentDate(Func):
4487class CurrentDate(Func):
4488    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4491class CurrentDatetime(Func):
4492    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4495class CurrentTime(Func):
4496    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4499class CurrentTimestamp(Func):
4500    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4503class CurrentUser(Func):
4504    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4507class DateAdd(Func, IntervalOp):
4508    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4511class DateSub(Func, IntervalOp):
4512    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4515class DateDiff(Func, TimeUnit):
4516    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4517    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4520class DateTrunc(Func):
4521    arg_types = {"unit": True, "this": True, "zone": False}
4522
4523    @property
4524    def unit(self) -> Expression:
4525        return self.args["unit"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4528class DatetimeAdd(Func, IntervalOp):
4529    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4532class DatetimeSub(Func, IntervalOp):
4533    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4536class DatetimeDiff(Func, TimeUnit):
4537    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4540class DatetimeTrunc(Func, TimeUnit):
4541    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4544class DayOfWeek(Func):
4545    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4548class DayOfMonth(Func):
4549    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4552class DayOfYear(Func):
4553    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4556class ToDays(Func):
4557    pass
key = 'todays'
class WeekOfYear(Func):
4560class WeekOfYear(Func):
4561    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4564class MonthsBetween(Func):
4565    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4568class LastDateOfMonth(Func):
4569    pass
key = 'lastdateofmonth'
class Extract(Func):
4572class Extract(Func):
4573    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4576class Timestamp(Func):
4577    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4580class TimestampAdd(Func, TimeUnit):
4581    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4584class TimestampSub(Func, TimeUnit):
4585    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4588class TimestampDiff(Func, TimeUnit):
4589    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4592class TimestampTrunc(Func, TimeUnit):
4593    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4596class TimeAdd(Func, TimeUnit):
4597    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4600class TimeSub(Func, TimeUnit):
4601    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4604class TimeDiff(Func, TimeUnit):
4605    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4608class TimeTrunc(Func, TimeUnit):
4609    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4612class DateFromParts(Func):
4613    _sql_names = ["DATEFROMPARTS"]
4614    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4617class DateStrToDate(Func):
4618    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4621class DateToDateStr(Func):
4622    pass
key = 'datetodatestr'
class DateToDi(Func):
4625class DateToDi(Func):
4626    pass
key = 'datetodi'
class Date(Func):
4630class Date(Func):
4631    arg_types = {"this": False, "zone": False, "expressions": False}
4632    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4635class Day(Func):
4636    pass
key = 'day'
class Decode(Func):
4639class Decode(Func):
4640    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4643class DiToDate(Func):
4644    pass
key = 'ditodate'
class Encode(Func):
4647class Encode(Func):
4648    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4651class Exp(Func):
4652    pass
key = 'exp'
class Explode(Func):
4656class Explode(Func):
4657    arg_types = {"this": True, "expressions": False}
4658    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4661class ExplodeOuter(Explode):
4662    pass
key = 'explodeouter'
class Posexplode(Explode):
4665class Posexplode(Explode):
4666    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4669class PosexplodeOuter(Posexplode):
4670    pass
key = 'posexplodeouter'
class Floor(Func):
4673class Floor(Func):
4674    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4677class FromBase64(Func):
4678    pass
key = 'frombase64'
class ToBase64(Func):
4681class ToBase64(Func):
4682    pass
key = 'tobase64'
class Greatest(Func):
4685class Greatest(Func):
4686    arg_types = {"this": True, "expressions": False}
4687    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4690class GroupConcat(AggFunc):
4691    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4694class Hex(Func):
4695    pass
key = 'hex'
class Xor(Connector, Func):
4698class Xor(Connector, Func):
4699    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4702class If(Func):
4703    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4706class Nullif(Func):
4707    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4710class Initcap(Func):
4711    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4714class IsNan(Func):
4715    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4718class IsInf(Func):
4719    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4722class FormatJson(Expression):
4723    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4726class JSONKeyValue(Expression):
4727    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4730class JSONObject(Func):
4731    arg_types = {
4732        "expressions": False,
4733        "null_handling": False,
4734        "unique_keys": False,
4735        "return_type": False,
4736        "encoding": False,
4737    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4741class JSONArray(Func):
4742    arg_types = {
4743        "expressions": True,
4744        "null_handling": False,
4745        "return_type": False,
4746        "strict": False,
4747    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4751class JSONArrayAgg(Func):
4752    arg_types = {
4753        "this": True,
4754        "order": False,
4755        "null_handling": False,
4756        "return_type": False,
4757        "strict": False,
4758    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4763class JSONColumnDef(Expression):
4764    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):
4767class JSONSchema(Expression):
4768    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4772class JSONTable(Func):
4773    arg_types = {
4774        "this": True,
4775        "schema": True,
4776        "path": False,
4777        "error_handling": False,
4778        "empty_handling": False,
4779    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4782class OpenJSONColumnDef(Expression):
4783    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):
4786class OpenJSON(Func):
4787    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4790class JSONBContains(Binary):
4791    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4794class JSONExtract(Binary, Func):
4795    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4798class JSONExtractScalar(JSONExtract):
4799    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4802class JSONBExtract(JSONExtract):
4803    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4806class JSONBExtractScalar(JSONExtract):
4807    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4810class JSONFormat(Func):
4811    arg_types = {"this": False, "options": False}
4812    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4816class JSONArrayContains(Binary, Predicate, Func):
4817    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4820class ParseJSON(Func):
4821    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4822    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4823    arg_types = {"this": True, "expressions": False}
4824    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
4827class Least(Func):
4828    arg_types = {"this": True, "expressions": False}
4829    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4832class Left(Func):
4833    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4840class Length(Func):
4841    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4844class Levenshtein(Func):
4845    arg_types = {
4846        "this": True,
4847        "expression": False,
4848        "ins_cost": False,
4849        "del_cost": False,
4850        "sub_cost": False,
4851    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4854class Ln(Func):
4855    pass
key = 'ln'
class Log(Func):
4858class Log(Func):
4859    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4862class Log2(Func):
4863    pass
key = 'log2'
class Log10(Func):
4866class Log10(Func):
4867    pass
key = 'log10'
class LogicalOr(AggFunc):
4870class LogicalOr(AggFunc):
4871    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4874class LogicalAnd(AggFunc):
4875    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4878class Lower(Func):
4879    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4882class Map(Func):
4883    arg_types = {"keys": False, "values": False}
4884
4885    @property
4886    def keys(self) -> t.List[Expression]:
4887        keys = self.args.get("keys")
4888        return keys.expressions if keys else []
4889
4890    @property
4891    def values(self) -> t.List[Expression]:
4892        values = self.args.get("values")
4893        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
values: List[Expression]
key = 'map'
class MapFromEntries(Func):
4896class MapFromEntries(Func):
4897    pass
key = 'mapfromentries'
class StarMap(Func):
4900class StarMap(Func):
4901    pass
key = 'starmap'
class VarMap(Func):
4904class VarMap(Func):
4905    arg_types = {"keys": True, "values": True}
4906    is_var_len_args = True
4907
4908    @property
4909    def keys(self) -> t.List[Expression]:
4910        return self.args["keys"].expressions
4911
4912    @property
4913    def values(self) -> t.List[Expression]:
4914        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
values: List[Expression]
key = 'varmap'
class MatchAgainst(Func):
4918class MatchAgainst(Func):
4919    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4922class Max(AggFunc):
4923    arg_types = {"this": True, "expressions": False}
4924    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4927class MD5(Func):
4928    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4932class MD5Digest(Func):
4933    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4936class Min(AggFunc):
4937    arg_types = {"this": True, "expressions": False}
4938    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4941class Month(Func):
4942    pass
key = 'month'
class Nvl2(Func):
4945class Nvl2(Func):
4946    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
4950class Predict(Func):
4951    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
4954class Pow(Binary, Func):
4955    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4958class PercentileCont(AggFunc):
4959    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4962class PercentileDisc(AggFunc):
4963    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4966class Quantile(AggFunc):
4967    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4970class ApproxQuantile(Quantile):
4971    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class RangeN(Func):
4974class RangeN(Func):
4975    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4978class ReadCSV(Func):
4979    _sql_names = ["READ_CSV"]
4980    is_var_len_args = True
4981    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4984class Reduce(Func):
4985    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):
4988class RegexpExtract(Func):
4989    arg_types = {
4990        "this": True,
4991        "expression": True,
4992        "position": False,
4993        "occurrence": False,
4994        "parameters": False,
4995        "group": False,
4996    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
4999class RegexpReplace(Func):
5000    arg_types = {
5001        "this": True,
5002        "expression": True,
5003        "replacement": True,
5004        "position": False,
5005        "occurrence": False,
5006        "parameters": False,
5007        "modifiers": False,
5008    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5011class RegexpLike(Binary, Func):
5012    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5015class RegexpILike(Binary, Func):
5016    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5021class RegexpSplit(Func):
5022    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5025class Repeat(Func):
5026    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5029class Round(Func):
5030    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5033class RowNumber(Func):
5034    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5037class SafeDivide(Func):
5038    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5041class SHA(Func):
5042    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5045class SHA2(Func):
5046    _sql_names = ["SHA2"]
5047    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5050class SortArray(Func):
5051    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5054class Split(Func):
5055    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5060class Substring(Func):
5061    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5064class StandardHash(Func):
5065    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5068class StartsWith(Func):
5069    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5070    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5073class StrPosition(Func):
5074    arg_types = {
5075        "this": True,
5076        "substr": True,
5077        "position": False,
5078        "instance": False,
5079    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5082class StrToDate(Func):
5083    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5086class StrToTime(Func):
5087    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5092class StrToUnix(Func):
5093    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5098class StrToMap(Func):
5099    arg_types = {
5100        "this": True,
5101        "pair_delim": False,
5102        "key_value_delim": False,
5103        "duplicate_resolution_callback": False,
5104    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5107class NumberToStr(Func):
5108    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5111class FromBase(Func):
5112    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5115class Struct(Func):
5116    arg_types = {"expressions": False}
5117    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5120class StructExtract(Func):
5121    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5126class Stuff(Func):
5127    _sql_names = ["STUFF", "INSERT"]
5128    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):
5131class Sum(AggFunc):
5132    pass
key = 'sum'
class Sqrt(Func):
5135class Sqrt(Func):
5136    pass
key = 'sqrt'
class Stddev(AggFunc):
5139class Stddev(AggFunc):
5140    pass
key = 'stddev'
class StddevPop(AggFunc):
5143class StddevPop(AggFunc):
5144    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5147class StddevSamp(AggFunc):
5148    pass
key = 'stddevsamp'
class TimeToStr(Func):
5151class TimeToStr(Func):
5152    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5155class TimeToTimeStr(Func):
5156    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5159class TimeToUnix(Func):
5160    pass
key = 'timetounix'
class TimeStrToDate(Func):
5163class TimeStrToDate(Func):
5164    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5167class TimeStrToTime(Func):
5168    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5171class TimeStrToUnix(Func):
5172    pass
key = 'timestrtounix'
class Trim(Func):
5175class Trim(Func):
5176    arg_types = {
5177        "this": True,
5178        "expression": False,
5179        "position": False,
5180        "collation": False,
5181    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5184class TsOrDsAdd(Func, TimeUnit):
5185    # return_type is used to correctly cast the arguments of this expression when transpiling it
5186    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5187
5188    @property
5189    def return_type(self) -> DataType:
5190        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
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5193class TsOrDsDiff(Func, TimeUnit):
5194    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5197class TsOrDsToDateStr(Func):
5198    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5201class TsOrDsToDate(Func):
5202    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
5205class TsOrDiToDi(Func):
5206    pass
key = 'tsorditodi'
class Unhex(Func):
5209class Unhex(Func):
5210    pass
key = 'unhex'
class UnixToStr(Func):
5213class UnixToStr(Func):
5214    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5219class UnixToTime(Func):
5220    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5221
5222    SECONDS = Literal.string("seconds")
5223    MILLIS = Literal.string("millis")
5224    MICROS = Literal.string("micros")
5225    NANOS = Literal.string("nanos")
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False}
SECONDS = (LITERAL this: seconds, is_string: True)
MILLIS = (LITERAL this: millis, is_string: True)
MICROS = (LITERAL this: micros, is_string: True)
NANOS = (LITERAL this: nanos, is_string: True)
key = 'unixtotime'
class UnixToTimeStr(Func):
5228class UnixToTimeStr(Func):
5229    pass
key = 'unixtotimestr'
class Upper(Func):
5232class Upper(Func):
5233    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5236class Variance(AggFunc):
5237    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5240class VariancePop(AggFunc):
5241    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5244class Week(Func):
5245    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5248class XMLTable(Func):
5249    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):
5252class Year(Func):
5253    pass
key = 'year'
class Use(Expression):
5256class Use(Expression):
5257    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5260class Merge(Expression):
5261    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):
5264class When(Func):
5265    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):
5270class NextValueFor(Func):
5271    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <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 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class '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 '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 'JSONTable'>, <class 'Last'>, <class 'LastDateOfMonth'>, <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 '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 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'Unhex'>, <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'>]
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:
5308def maybe_parse(
5309    sql_or_expression: ExpOrStr,
5310    *,
5311    into: t.Optional[IntoType] = None,
5312    dialect: DialectType = None,
5313    prefix: t.Optional[str] = None,
5314    copy: bool = False,
5315    **opts,
5316) -> Expression:
5317    """Gracefully handle a possible string or expression.
5318
5319    Example:
5320        >>> maybe_parse("1")
5321        (LITERAL this: 1, is_string: False)
5322        >>> maybe_parse(to_identifier("x"))
5323        (IDENTIFIER this: x, quoted: False)
5324
5325    Args:
5326        sql_or_expression: the SQL code string or an expression
5327        into: the SQLGlot Expression to parse into
5328        dialect: the dialect used to parse the input expressions (in the case that an
5329            input expression is a SQL string).
5330        prefix: a string to prefix the sql with before it gets parsed
5331            (automatically includes a space)
5332        copy: whether or not to copy the expression.
5333        **opts: other options to use to parse the input expressions (again, in the case
5334            that an input expression is a SQL string).
5335
5336    Returns:
5337        Expression: the parsed or given expression.
5338    """
5339    if isinstance(sql_or_expression, Expression):
5340        if copy:
5341            return sql_or_expression.copy()
5342        return sql_or_expression
5343
5344    if sql_or_expression is None:
5345        raise ParseError(f"SQL cannot be None")
5346
5347    import sqlglot
5348
5349    sql = str(sql_or_expression)
5350    if prefix:
5351        sql = f"{prefix} {sql}"
5352
5353    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)

Gracefully handle a possible string or expression.

Example:
>>> maybe_parse("1")
(LITERAL this: 1, is_string: False)
>>> maybe_parse(to_identifier("x"))
(IDENTIFIER this: x, quoted: False)
Arguments:
  • sql_or_expression: the SQL code string or an expression
  • into: the SQLGlot Expression to parse into
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • prefix: a string to prefix the sql with before it gets parsed (automatically includes a space)
  • copy: whether or not to copy the expression.
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Expression: the parsed or given expression.

def maybe_copy(instance, copy=True):
5366def maybe_copy(instance, copy=True):
5367    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:
5548def union(
5549    left: ExpOrStr,
5550    right: ExpOrStr,
5551    distinct: bool = True,
5552    dialect: DialectType = None,
5553    copy: bool = True,
5554    **opts,
5555) -> Union:
5556    """
5557    Initializes a syntax tree from one UNION expression.
5558
5559    Example:
5560        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5561        'SELECT * FROM foo UNION SELECT * FROM bla'
5562
5563    Args:
5564        left: the SQL code string corresponding to the left-hand side.
5565            If an `Expression` instance is passed, it will be used as-is.
5566        right: the SQL code string corresponding to the right-hand side.
5567            If an `Expression` instance is passed, it will be used as-is.
5568        distinct: set the DISTINCT flag if and only if this is true.
5569        dialect: the dialect used to parse the input expression.
5570        copy: whether or not to copy the expression.
5571        opts: other options to use to parse the input expressions.
5572
5573    Returns:
5574        The new Union instance.
5575    """
5576    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5577    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5578
5579    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
5582def intersect(
5583    left: ExpOrStr,
5584    right: ExpOrStr,
5585    distinct: bool = True,
5586    dialect: DialectType = None,
5587    copy: bool = True,
5588    **opts,
5589) -> Intersect:
5590    """
5591    Initializes a syntax tree from one INTERSECT expression.
5592
5593    Example:
5594        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5595        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5596
5597    Args:
5598        left: the SQL code string corresponding to the left-hand side.
5599            If an `Expression` instance is passed, it will be used as-is.
5600        right: the SQL code string corresponding to the right-hand side.
5601            If an `Expression` instance is passed, it will be used as-is.
5602        distinct: set the DISTINCT flag if and only if this is true.
5603        dialect: the dialect used to parse the input expression.
5604        copy: whether or not to copy the expression.
5605        opts: other options to use to parse the input expressions.
5606
5607    Returns:
5608        The new Intersect instance.
5609    """
5610    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5611    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5612
5613    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
5616def except_(
5617    left: ExpOrStr,
5618    right: ExpOrStr,
5619    distinct: bool = True,
5620    dialect: DialectType = None,
5621    copy: bool = True,
5622    **opts,
5623) -> Except:
5624    """
5625    Initializes a syntax tree from one EXCEPT expression.
5626
5627    Example:
5628        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5629        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5630
5631    Args:
5632        left: the SQL code string corresponding to the left-hand side.
5633            If an `Expression` instance is passed, it will be used as-is.
5634        right: the SQL code string corresponding to the right-hand side.
5635            If an `Expression` instance is passed, it will be used as-is.
5636        distinct: set the DISTINCT flag if and only if this is true.
5637        dialect: the dialect used to parse the input expression.
5638        copy: whether or not to copy the expression.
5639        opts: other options to use to parse the input expressions.
5640
5641    Returns:
5642        The new Except instance.
5643    """
5644    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5645    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5646
5647    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
5650def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5651    """
5652    Initializes a syntax tree from one or multiple SELECT expressions.
5653
5654    Example:
5655        >>> select("col1", "col2").from_("tbl").sql()
5656        'SELECT col1, col2 FROM tbl'
5657
5658    Args:
5659        *expressions: the SQL code string to parse as the expressions of a
5660            SELECT statement. If an Expression instance is passed, this is used as-is.
5661        dialect: the dialect used to parse the input expressions (in the case that an
5662            input expression is a SQL string).
5663        **opts: other options to use to parse the input expressions (again, in the case
5664            that an input expression is a SQL string).
5665
5666    Returns:
5667        Select: the syntax tree for the SELECT statement.
5668    """
5669    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:
5672def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5673    """
5674    Initializes a syntax tree from a FROM expression.
5675
5676    Example:
5677        >>> from_("tbl").select("col1", "col2").sql()
5678        'SELECT col1, col2 FROM tbl'
5679
5680    Args:
5681        *expression: the SQL code string to parse as the FROM expressions of a
5682            SELECT statement. If an Expression instance is passed, this is used as-is.
5683        dialect: the dialect used to parse the input expression (in the case that the
5684            input expression is a SQL string).
5685        **opts: other options to use to parse the input expressions (again, in the case
5686            that the input expression is a SQL string).
5687
5688    Returns:
5689        Select: the syntax tree for the SELECT statement.
5690    """
5691    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:
5694def update(
5695    table: str | Table,
5696    properties: dict,
5697    where: t.Optional[ExpOrStr] = None,
5698    from_: t.Optional[ExpOrStr] = None,
5699    dialect: DialectType = None,
5700    **opts,
5701) -> Update:
5702    """
5703    Creates an update statement.
5704
5705    Example:
5706        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5707        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5708
5709    Args:
5710        *properties: dictionary of properties to set which are
5711            auto converted to sql objects eg None -> NULL
5712        where: sql conditional parsed into a WHERE statement
5713        from_: sql statement parsed into a FROM statement
5714        dialect: the dialect used to parse the input expressions.
5715        **opts: other options to use to parse the input expressions.
5716
5717    Returns:
5718        Update: the syntax tree for the UPDATE statement.
5719    """
5720    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5721    update_expr.set(
5722        "expressions",
5723        [
5724            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5725            for k, v in properties.items()
5726        ],
5727    )
5728    if from_:
5729        update_expr.set(
5730            "from",
5731            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5732        )
5733    if isinstance(where, Condition):
5734        where = Where(this=where)
5735    if where:
5736        update_expr.set(
5737            "where",
5738            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5739        )
5740    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:
5743def delete(
5744    table: ExpOrStr,
5745    where: t.Optional[ExpOrStr] = None,
5746    returning: t.Optional[ExpOrStr] = None,
5747    dialect: DialectType = None,
5748    **opts,
5749) -> Delete:
5750    """
5751    Builds a delete statement.
5752
5753    Example:
5754        >>> delete("my_table", where="id > 1").sql()
5755        'DELETE FROM my_table WHERE id > 1'
5756
5757    Args:
5758        where: sql conditional parsed into a WHERE statement
5759        returning: sql conditional parsed into a RETURNING statement
5760        dialect: the dialect used to parse the input expressions.
5761        **opts: other options to use to parse the input expressions.
5762
5763    Returns:
5764        Delete: the syntax tree for the DELETE statement.
5765    """
5766    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5767    if where:
5768        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5769    if returning:
5770        delete_expr = t.cast(
5771            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5772        )
5773    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[Union[str, Expression]]] = 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:
5776def insert(
5777    expression: ExpOrStr,
5778    into: ExpOrStr,
5779    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5780    overwrite: t.Optional[bool] = None,
5781    returning: t.Optional[ExpOrStr] = None,
5782    dialect: DialectType = None,
5783    copy: bool = True,
5784    **opts,
5785) -> Insert:
5786    """
5787    Builds an INSERT statement.
5788
5789    Example:
5790        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5791        'INSERT INTO tbl VALUES (1, 2, 3)'
5792
5793    Args:
5794        expression: the sql string or expression of the INSERT statement
5795        into: the tbl to insert data to.
5796        columns: optionally the table's column names.
5797        overwrite: whether to INSERT OVERWRITE or not.
5798        returning: sql conditional parsed into a RETURNING statement
5799        dialect: the dialect used to parse the input expressions.
5800        copy: whether or not to copy the expression.
5801        **opts: other options to use to parse the input expressions.
5802
5803    Returns:
5804        Insert: the syntax tree for the INSERT statement.
5805    """
5806    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5807    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5808
5809    if columns:
5810        this = _apply_list_builder(
5811            *columns,
5812            instance=Schema(this=this),
5813            arg="expressions",
5814            into=Identifier,
5815            copy=False,
5816            dialect=dialect,
5817            **opts,
5818        )
5819
5820    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5821
5822    if returning:
5823        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5824
5825    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether or not to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
5828def condition(
5829    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5830) -> Condition:
5831    """
5832    Initialize a logical condition expression.
5833
5834    Example:
5835        >>> condition("x=1").sql()
5836        'x = 1'
5837
5838        This is helpful for composing larger logical syntax trees:
5839        >>> where = condition("x=1")
5840        >>> where = where.and_("y=1")
5841        >>> Select().from_("tbl").select("*").where(where).sql()
5842        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5843
5844    Args:
5845        *expression: the SQL code string to parse.
5846            If an Expression instance is passed, this is used as-is.
5847        dialect: the dialect used to parse the input expression (in the case that the
5848            input expression is a SQL string).
5849        copy: Whether or not to copy `expression` (only applies to expressions).
5850        **opts: other options to use to parse the input expressions (again, in the case
5851            that the input expression is a SQL string).
5852
5853    Returns:
5854        The new Condition instance
5855    """
5856    return maybe_parse(
5857        expression,
5858        into=Condition,
5859        dialect=dialect,
5860        copy=copy,
5861        **opts,
5862    )

Initialize a logical condition expression.

Example:
>>> condition("x=1").sql()
'x = 1'

This is helpful for composing larger logical syntax trees:

>>> where = condition("x=1")
>>> where = where.and_("y=1")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • copy: Whether or not to copy expression (only applies to expressions).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
5865def and_(
5866    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5867) -> Condition:
5868    """
5869    Combine multiple conditions with an AND logical operator.
5870
5871    Example:
5872        >>> and_("x=1", and_("y=1", "z=1")).sql()
5873        'x = 1 AND (y = 1 AND z = 1)'
5874
5875    Args:
5876        *expressions: the SQL code strings to parse.
5877            If an Expression instance is passed, this is used as-is.
5878        dialect: the dialect used to parse the input expression.
5879        copy: whether or not to copy `expressions` (only applies to Expressions).
5880        **opts: other options to use to parse the input expressions.
5881
5882    Returns:
5883        And: the new condition
5884    """
5885    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))

Combine multiple conditions with an AND logical operator.

Example:
>>> and_("x=1", and_("y=1", "z=1")).sql()
'x = 1 AND (y = 1 AND z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

And: the new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
5888def or_(
5889    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5890) -> Condition:
5891    """
5892    Combine multiple conditions with an OR logical operator.
5893
5894    Example:
5895        >>> or_("x=1", or_("y=1", "z=1")).sql()
5896        'x = 1 OR (y = 1 OR z = 1)'
5897
5898    Args:
5899        *expressions: the SQL code strings to parse.
5900            If an Expression instance is passed, this is used as-is.
5901        dialect: the dialect used to parse the input expression.
5902        copy: whether or not to copy `expressions` (only applies to Expressions).
5903        **opts: other options to use to parse the input expressions.
5904
5905    Returns:
5906        Or: the new condition
5907    """
5908    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))

Combine multiple conditions with an OR logical operator.

Example:
>>> or_("x=1", or_("y=1", "z=1")).sql()
'x = 1 OR (y = 1 OR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

Or: the new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
5911def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5912    """
5913    Wrap a condition with a NOT operator.
5914
5915    Example:
5916        >>> not_("this_suit='black'").sql()
5917        "NOT this_suit = 'black'"
5918
5919    Args:
5920        expression: the SQL code string to parse.
5921            If an Expression instance is passed, this is used as-is.
5922        dialect: the dialect used to parse the input expression.
5923        copy: whether to copy the expression or not.
5924        **opts: other options to use to parse the input expressions.
5925
5926    Returns:
5927        The new condition.
5928    """
5929    this = condition(
5930        expression,
5931        dialect=dialect,
5932        copy=copy,
5933        **opts,
5934    )
5935    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:
5938def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5939    """
5940    Wrap an expression in parentheses.
5941
5942    Example:
5943        >>> paren("5 + 3").sql()
5944        '(5 + 3)'
5945
5946    Args:
5947        expression: the SQL code string to parse.
5948            If an Expression instance is passed, this is used as-is.
5949        copy: whether to copy the expression or not.
5950
5951    Returns:
5952        The wrapped expression.
5953    """
5954    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 = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
5972def to_identifier(name, quoted=None, copy=True):
5973    """Builds an identifier.
5974
5975    Args:
5976        name: The name to turn into an identifier.
5977        quoted: Whether or not force quote the identifier.
5978        copy: Whether or not to copy name if it's an Identifier.
5979
5980    Returns:
5981        The identifier ast node.
5982    """
5983
5984    if name is None:
5985        return None
5986
5987    if isinstance(name, Identifier):
5988        identifier = maybe_copy(name, copy)
5989    elif isinstance(name, str):
5990        identifier = Identifier(
5991            this=name,
5992            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
5993        )
5994    else:
5995        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
5996    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether or not force quote the identifier.
  • copy: Whether or not to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
5999def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6000    """
6001    Parses a given string into an identifier.
6002
6003    Args:
6004        name: The name to parse into an identifier.
6005        dialect: The dialect to parse against.
6006
6007    Returns:
6008        The identifier ast node.
6009    """
6010    try:
6011        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6012    except ParseError:
6013        expression = to_identifier(name)
6014
6015    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:
6021def to_interval(interval: str | Literal) -> Interval:
6022    """Builds an interval expression from a string like '1 day' or '5 months'."""
6023    if isinstance(interval, Literal):
6024        if not interval.is_string:
6025            raise ValueError("Invalid interval string.")
6026
6027        interval = interval.this
6028
6029    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6030
6031    if not interval_parts:
6032        raise ValueError("Invalid interval string.")
6033
6034    return Interval(
6035        this=Literal.string(interval_parts.group(1)),
6036        unit=Var(this=interval_parts.group(2)),
6037    )

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]:
6050def to_table(
6051    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6052) -> t.Optional[Table]:
6053    """
6054    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6055    If a table is passed in then that table is returned.
6056
6057    Args:
6058        sql_path: a `[catalog].[schema].[table]` string.
6059        dialect: the source dialect according to which the table name will be parsed.
6060        copy: Whether or not to copy a table if it is passed in.
6061        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6062
6063    Returns:
6064        A table expression.
6065    """
6066    if sql_path is None or isinstance(sql_path, Table):
6067        return maybe_copy(sql_path, copy=copy)
6068    if not isinstance(sql_path, str):
6069        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6070
6071    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6072    if table:
6073        for k, v in kwargs.items():
6074            table.set(k, v)
6075
6076    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether or not to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
6079def to_column(sql_path: str | Column, **kwargs) -> Column:
6080    """
6081    Create a column from a `[table].[column]` sql path. Schema is optional.
6082
6083    If a column is passed in then that column is returned.
6084
6085    Args:
6086        sql_path: `[table].[column]` string
6087    Returns:
6088        Table: A column expression
6089    """
6090    if sql_path is None or isinstance(sql_path, Column):
6091        return sql_path
6092    if not isinstance(sql_path, str):
6093        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6094    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore

Create a column from a [table].[column] sql path. Schema is optional.

If a column is passed in then that column is returned.

Arguments:
  • sql_path: [table].[column] string
Returns:

Table: A column expression

def alias_( expression: Union[str, Expression], alias: str | Identifier, table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
6097def alias_(
6098    expression: ExpOrStr,
6099    alias: str | Identifier,
6100    table: bool | t.Sequence[str | Identifier] = False,
6101    quoted: t.Optional[bool] = None,
6102    dialect: DialectType = None,
6103    copy: bool = True,
6104    **opts,
6105):
6106    """Create an Alias expression.
6107
6108    Example:
6109        >>> alias_('foo', 'bar').sql()
6110        'foo AS bar'
6111
6112        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6113        '(SELECT 1, 2) AS bar(a, b)'
6114
6115    Args:
6116        expression: the SQL code strings to parse.
6117            If an Expression instance is passed, this is used as-is.
6118        alias: the alias name to use. If the name has
6119            special characters it is quoted.
6120        table: Whether or not to create a table alias, can also be a list of columns.
6121        quoted: whether or not to quote the alias
6122        dialect: the dialect used to parse the input expression.
6123        copy: Whether or not to copy the expression.
6124        **opts: other options to use to parse the input expressions.
6125
6126    Returns:
6127        Alias: the aliased expression
6128    """
6129    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6130    alias = to_identifier(alias, quoted=quoted)
6131
6132    if table:
6133        table_alias = TableAlias(this=alias)
6134        exp.set("alias", table_alias)
6135
6136        if not isinstance(table, bool):
6137            for column in table:
6138                table_alias.append("columns", to_identifier(column, quoted=quoted))
6139
6140        return exp
6141
6142    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6143    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6144    # for the complete Window expression.
6145    #
6146    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6147
6148    if "alias" in exp.arg_types and not isinstance(exp, Window):
6149        exp.set("alias", alias)
6150        return exp
6151    return Alias(this=exp, alias=alias)

Create an Alias expression.

Example:
>>> alias_('foo', 'bar').sql()
'foo AS bar'
>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
'(SELECT 1, 2) AS bar(a, b)'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use. If the name has special characters it is quoted.
  • table: Whether or not to create a table alias, can also be a list of columns.
  • quoted: whether or not to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether or not to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6154def subquery(
6155    expression: ExpOrStr,
6156    alias: t.Optional[Identifier | str] = None,
6157    dialect: DialectType = None,
6158    **opts,
6159) -> Select:
6160    """
6161    Build a subquery expression.
6162
6163    Example:
6164        >>> subquery('select x from tbl', 'bar').select('x').sql()
6165        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6166
6167    Args:
6168        expression: the SQL code strings to parse.
6169            If an Expression instance is passed, this is used as-is.
6170        alias: the alias name to use.
6171        dialect: the dialect used to parse the input expression.
6172        **opts: other options to use to parse the input expressions.
6173
6174    Returns:
6175        A new Select instance with the subquery expression included.
6176    """
6177
6178    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6179    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: str | Identifier, table: Union[Identifier, str, NoneType] = None, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None) -> Column:
6182def column(
6183    col: str | Identifier,
6184    table: t.Optional[str | Identifier] = None,
6185    db: t.Optional[str | Identifier] = None,
6186    catalog: t.Optional[str | Identifier] = None,
6187    quoted: t.Optional[bool] = None,
6188) -> Column:
6189    """
6190    Build a Column.
6191
6192    Args:
6193        col: Column name.
6194        table: Table name.
6195        db: Database name.
6196        catalog: Catalog name.
6197        quoted: Whether to force quotes on the column's identifiers.
6198
6199    Returns:
6200        The new Column instance.
6201    """
6202    return Column(
6203        this=to_identifier(col, quoted=quoted),
6204        table=to_identifier(table, quoted=quoted),
6205        db=to_identifier(db, quoted=quoted),
6206        catalog=to_identifier(catalog, quoted=quoted),
6207    )

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • quoted: Whether to force quotes on the column's identifiers.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], **opts) -> Cast:
6210def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6211    """Cast an expression to a data type.
6212
6213    Example:
6214        >>> cast('x + 1', 'int').sql()
6215        'CAST(x + 1 AS INT)'
6216
6217    Args:
6218        expression: The expression to cast.
6219        to: The datatype to cast to.
6220
6221    Returns:
6222        The new Cast instance.
6223    """
6224    expression = maybe_parse(expression, **opts)
6225    data_type = DataType.build(to, **opts)
6226    expression = Cast(this=expression, to=data_type)
6227    expression.type = data_type
6228    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.
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:
6231def table_(
6232    table: Identifier | str,
6233    db: t.Optional[Identifier | str] = None,
6234    catalog: t.Optional[Identifier | str] = None,
6235    quoted: t.Optional[bool] = None,
6236    alias: t.Optional[Identifier | str] = None,
6237) -> Table:
6238    """Build a Table.
6239
6240    Args:
6241        table: Table name.
6242        db: Database name.
6243        catalog: Catalog name.
6244        quote: Whether to force quotes on the table's identifiers.
6245        alias: Table's alias.
6246
6247    Returns:
6248        The new Table instance.
6249    """
6250    return Table(
6251        this=to_identifier(table, quoted=quoted) if table else None,
6252        db=to_identifier(db, quoted=quoted) if db else None,
6253        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6254        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6255    )

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:
6258def values(
6259    values: t.Iterable[t.Tuple[t.Any, ...]],
6260    alias: t.Optional[str] = None,
6261    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6262) -> Values:
6263    """Build VALUES statement.
6264
6265    Example:
6266        >>> values([(1, '2')]).sql()
6267        "VALUES (1, '2')"
6268
6269    Args:
6270        values: values statements that will be converted to SQL
6271        alias: optional alias
6272        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6273         If either are provided then an alias is also required.
6274
6275    Returns:
6276        Values: the Values expression object
6277    """
6278    if columns and not alias:
6279        raise ValueError("Alias is required when providing columns")
6280
6281    return Values(
6282        expressions=[convert(tup) for tup in values],
6283        alias=(
6284            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6285            if columns
6286            else (TableAlias(this=to_identifier(alias)) if alias else None)
6287        ),
6288    )

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:
6291def var(name: t.Optional[ExpOrStr]) -> Var:
6292    """Build a SQL variable.
6293
6294    Example:
6295        >>> repr(var('x'))
6296        '(VAR this: x)'
6297
6298        >>> repr(var(column('x', table='y')))
6299        '(VAR this: x)'
6300
6301    Args:
6302        name: The name of the var or an expression who's name will become the var.
6303
6304    Returns:
6305        The new variable node.
6306    """
6307    if not name:
6308        raise ValueError("Cannot convert empty name into var.")
6309
6310    if isinstance(name, Expression):
6311        name = name.name
6312    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:
6315def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6316    """Build ALTER TABLE... RENAME... expression
6317
6318    Args:
6319        old_name: The old name of the table
6320        new_name: The new name of the table
6321
6322    Returns:
6323        Alter table expression
6324    """
6325    old_table = to_table(old_name)
6326    new_table = to_table(new_name)
6327    return AlterTable(
6328        this=old_table,
6329        actions=[
6330            RenameTable(this=new_table),
6331        ],
6332    )

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 convert(value: Any, copy: bool = False) -> Expression:
6335def convert(value: t.Any, copy: bool = False) -> Expression:
6336    """Convert a python value into an expression object.
6337
6338    Raises an error if a conversion is not possible.
6339
6340    Args:
6341        value: A python object.
6342        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6343
6344    Returns:
6345        Expression: the equivalent expression object.
6346    """
6347    if isinstance(value, Expression):
6348        return maybe_copy(value, copy)
6349    if isinstance(value, str):
6350        return Literal.string(value)
6351    if isinstance(value, bool):
6352        return Boolean(this=value)
6353    if value is None or (isinstance(value, float) and math.isnan(value)):
6354        return NULL
6355    if isinstance(value, numbers.Number):
6356        return Literal.number(value)
6357    if isinstance(value, datetime.datetime):
6358        datetime_literal = Literal.string(
6359            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6360        )
6361        return TimeStrToTime(this=datetime_literal)
6362    if isinstance(value, datetime.date):
6363        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6364        return DateStrToDate(this=date_literal)
6365    if isinstance(value, tuple):
6366        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6367    if isinstance(value, list):
6368        return Array(expressions=[convert(v, copy=copy) for v in value])
6369    if isinstance(value, dict):
6370        return Map(
6371            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6372            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6373        )
6374    raise ValueError(f"Cannot convert {value}")

Convert a python value into an expression object.

Raises an error if a conversion is not possible.

Arguments:
  • value: A python object.
  • copy: Whether or not to copy value (only applies to Expressions and collections).
Returns:

Expression: the equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
6377def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6378    """
6379    Replace children of an expression with the result of a lambda fun(child) -> exp.
6380    """
6381    for k, v in expression.args.items():
6382        is_list_arg = type(v) is list
6383
6384        child_nodes = v if is_list_arg else [v]
6385        new_child_nodes = []
6386
6387        for cn in child_nodes:
6388            if isinstance(cn, Expression):
6389                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6390                    new_child_nodes.append(child_node)
6391                    child_node.parent = expression
6392                    child_node.arg_key = k
6393            else:
6394                new_child_nodes.append(cn)
6395
6396        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]:
6399def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6400    """
6401    Return all table names referenced through columns in an expression.
6402
6403    Example:
6404        >>> import sqlglot
6405        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6406        ['a', 'c']
6407
6408    Args:
6409        expression: expression to find table names.
6410        exclude: a table name to exclude
6411
6412    Returns:
6413        A list of unique names.
6414    """
6415    return {
6416        table
6417        for table in (column.table for column in expression.find_all(Column))
6418        if table and table != exclude
6419    }

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:
6422def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6423    """Get the full name of a table as a string.
6424
6425    Args:
6426        table: Table expression node or string.
6427        dialect: The dialect to generate the table name for.
6428        identify: Determines when an identifier should be quoted. Possible values are:
6429            False (default): Never quote, except in cases where it's mandatory by the dialect.
6430            True: Always quote.
6431
6432    Examples:
6433        >>> from sqlglot import exp, parse_one
6434        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6435        'a.b.c'
6436
6437    Returns:
6438        The table name.
6439    """
6440
6441    table = maybe_parse(table, into=Table, dialect=dialect)
6442
6443    if not table:
6444        raise ValueError(f"Cannot parse {table}")
6445
6446    return ".".join(
6447        part.sql(dialect=dialect, identify=True)
6448        if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6449        else part.name
6450        for part in table.parts
6451    )

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:
6454def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6455    """Returns a case normalized table name without quotes.
6456
6457    Args:
6458        table: the table to normalize
6459        dialect: the dialect to use for normalization rules
6460        copy: whether or not to copy the expression.
6461
6462    Examples:
6463        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6464        'A-B.c'
6465    """
6466    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6467
6468    return ".".join(
6469        p.name
6470        for p in normalize_identifiers(
6471            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6472        ).parts
6473    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether or not to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
6476def replace_tables(
6477    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6478) -> E:
6479    """Replace all tables in expression according to the mapping.
6480
6481    Args:
6482        expression: expression node to be transformed and replaced.
6483        mapping: mapping of table names.
6484        dialect: the dialect of the mapping table
6485        copy: whether or not to copy the expression.
6486
6487    Examples:
6488        >>> from sqlglot import exp, parse_one
6489        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6490        'SELECT * FROM c'
6491
6492    Returns:
6493        The mapped expression.
6494    """
6495
6496    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6497
6498    def _replace_tables(node: Expression) -> Expression:
6499        if isinstance(node, Table):
6500            new_name = mapping.get(normalize_table_name(node, dialect=dialect))
6501
6502            if new_name:
6503                return to_table(
6504                    new_name,
6505                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6506                )
6507        return node
6508
6509    return expression.transform(_replace_tables, copy=copy)

Replace all tables in expression according to the mapping.

Arguments:
  • expression: expression node to be transformed and replaced.
  • mapping: mapping of table names.
  • dialect: the dialect of the mapping table
  • copy: whether or not to copy the expression.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
'SELECT * FROM c'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
6512def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6513    """Replace placeholders in an expression.
6514
6515    Args:
6516        expression: expression node to be transformed and replaced.
6517        args: positional names that will substitute unnamed placeholders in the given order.
6518        kwargs: keyword arguments that will substitute named placeholders.
6519
6520    Examples:
6521        >>> from sqlglot import exp, parse_one
6522        >>> replace_placeholders(
6523        ...     parse_one("select * from :tbl where ? = ?"),
6524        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6525        ... ).sql()
6526        "SELECT * FROM foo WHERE str_col = 'b'"
6527
6528    Returns:
6529        The mapped expression.
6530    """
6531
6532    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6533        if isinstance(node, Placeholder):
6534            if node.name:
6535                new_name = kwargs.get(node.name)
6536                if new_name:
6537                    return convert(new_name)
6538            else:
6539                try:
6540                    return convert(next(args))
6541                except StopIteration:
6542                    pass
6543        return node
6544
6545    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:
6548def expand(
6549    expression: Expression,
6550    sources: t.Dict[str, Subqueryable],
6551    dialect: DialectType = None,
6552    copy: bool = True,
6553) -> Expression:
6554    """Transforms an expression by expanding all referenced sources into subqueries.
6555
6556    Examples:
6557        >>> from sqlglot import parse_one
6558        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6559        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6560
6561        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6562        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6563
6564    Args:
6565        expression: The expression to expand.
6566        sources: A dictionary of name to Subqueryables.
6567        dialect: The dialect of the sources dict.
6568        copy: Whether or not to copy the expression during transformation. Defaults to True.
6569
6570    Returns:
6571        The transformed expression.
6572    """
6573    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6574
6575    def _expand(node: Expression):
6576        if isinstance(node, Table):
6577            name = normalize_table_name(node, dialect=dialect)
6578            source = sources.get(name)
6579            if source:
6580                subquery = source.subquery(node.alias or name)
6581                subquery.comments = [f"source: {name}"]
6582                return subquery.transform(_expand, copy=False)
6583        return node
6584
6585    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dictionary of name to Subqueryables.
  • dialect: The dialect of the sources dict.
  • copy: Whether or not to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
6588def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6589    """
6590    Returns a Func expression.
6591
6592    Examples:
6593        >>> func("abs", 5).sql()
6594        'ABS(5)'
6595
6596        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6597        'CAST(5 AS DOUBLE)'
6598
6599    Args:
6600        name: the name of the function to build.
6601        args: the args used to instantiate the function of interest.
6602        dialect: the source dialect.
6603        kwargs: the kwargs used to instantiate the function of interest.
6604
6605    Note:
6606        The arguments `args` and `kwargs` are mutually exclusive.
6607
6608    Returns:
6609        An instance of the function of interest, or an anonymous function, if `name` doesn't
6610        correspond to an existing `sqlglot.expressions.Func` class.
6611    """
6612    if args and kwargs:
6613        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6614
6615    from sqlglot.dialects.dialect import Dialect
6616
6617    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6618    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6619
6620    parser = Dialect.get_or_raise(dialect)().parser()
6621    from_args_list = parser.FUNCTIONS.get(name.upper())
6622
6623    if from_args_list:
6624        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6625    else:
6626        kwargs = kwargs or {"expressions": converted}
6627        function = Anonymous(this=name, **kwargs)
6628
6629    for error_message in function.error_messages(converted):
6630        raise ValueError(error_message)
6631
6632    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.
  • 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:
6635def case(
6636    expression: t.Optional[ExpOrStr] = None,
6637    **opts,
6638) -> Case:
6639    """
6640    Initialize a CASE statement.
6641
6642    Example:
6643        case().when("a = 1", "foo").else_("bar")
6644
6645    Args:
6646        expression: Optionally, the input expression (not all dialects support this)
6647        **opts: Extra keyword arguments for parsing `expression`
6648    """
6649    if expression is not None:
6650        this = maybe_parse(expression, **opts)
6651    else:
6652        this = None
6653    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 true() -> Boolean:
6656def true() -> Boolean:
6657    """
6658    Returns a true Boolean expression.
6659    """
6660    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6663def false() -> Boolean:
6664    """
6665    Returns a false Boolean expression.
6666    """
6667    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6670def null() -> Null:
6671    """
6672    Returns a Null expression.
6673    """
6674    return Null()

Returns a Null expression.

TRUE = (BOOLEAN this: True)
FALSE = (BOOLEAN this: False)
NULL = (NULL )