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    pass
3948
3949
3950class SafeDPipe(DPipe):
3951    pass
3952
3953
3954class EQ(Binary, Predicate):
3955    pass
3956
3957
3958class NullSafeEQ(Binary, Predicate):
3959    pass
3960
3961
3962class NullSafeNEQ(Binary, Predicate):
3963    pass
3964
3965
3966# Represents e.g. := in DuckDB which is mostly used for setting parameters
3967class PropertyEQ(Binary):
3968    pass
3969
3970
3971class Distance(Binary):
3972    pass
3973
3974
3975class Escape(Binary):
3976    pass
3977
3978
3979class Glob(Binary, Predicate):
3980    pass
3981
3982
3983class GT(Binary, Predicate):
3984    pass
3985
3986
3987class GTE(Binary, Predicate):
3988    pass
3989
3990
3991class ILike(Binary, Predicate):
3992    pass
3993
3994
3995class ILikeAny(Binary, Predicate):
3996    pass
3997
3998
3999class IntDiv(Binary):
4000    pass
4001
4002
4003class Is(Binary, Predicate):
4004    pass
4005
4006
4007class Kwarg(Binary):
4008    """Kwarg in special functions like func(kwarg => y)."""
4009
4010
4011class Like(Binary, Predicate):
4012    pass
4013
4014
4015class LikeAny(Binary, Predicate):
4016    pass
4017
4018
4019class LT(Binary, Predicate):
4020    pass
4021
4022
4023class LTE(Binary, Predicate):
4024    pass
4025
4026
4027class Mod(Binary):
4028    pass
4029
4030
4031class Mul(Binary):
4032    pass
4033
4034
4035class NEQ(Binary, Predicate):
4036    pass
4037
4038
4039# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
4040class Operator(Binary):
4041    arg_types = {"this": True, "operator": True, "expression": True}
4042
4043
4044class SimilarTo(Binary, Predicate):
4045    pass
4046
4047
4048class Slice(Binary):
4049    arg_types = {"this": False, "expression": False}
4050
4051
4052class Sub(Binary):
4053    pass
4054
4055
4056class ArrayOverlaps(Binary):
4057    pass
4058
4059
4060# Unary Expressions
4061# (NOT a)
4062class Unary(Condition):
4063    pass
4064
4065
4066class BitwiseNot(Unary):
4067    pass
4068
4069
4070class Not(Unary):
4071    pass
4072
4073
4074class Paren(Unary):
4075    arg_types = {"this": True, "with": False}
4076
4077    @property
4078    def output_name(self) -> str:
4079        return self.this.name
4080
4081
4082class Neg(Unary):
4083    pass
4084
4085
4086class Alias(Expression):
4087    arg_types = {"this": True, "alias": False}
4088
4089    @property
4090    def output_name(self) -> str:
4091        return self.alias
4092
4093
4094class Aliases(Expression):
4095    arg_types = {"this": True, "expressions": True}
4096
4097    @property
4098    def aliases(self):
4099        return self.expressions
4100
4101
4102class AtTimeZone(Expression):
4103    arg_types = {"this": True, "zone": True}
4104
4105
4106class Between(Predicate):
4107    arg_types = {"this": True, "low": True, "high": True}
4108
4109
4110class Bracket(Condition):
4111    arg_types = {"this": True, "expressions": True}
4112
4113    @property
4114    def output_name(self) -> str:
4115        if len(self.expressions) == 1:
4116            return self.expressions[0].output_name
4117
4118        return super().output_name
4119
4120
4121class SafeBracket(Bracket):
4122    """Represents array lookup where OOB index yields NULL instead of causing a failure."""
4123
4124
4125class Distinct(Expression):
4126    arg_types = {"expressions": False, "on": False}
4127
4128
4129class In(Predicate):
4130    arg_types = {
4131        "this": True,
4132        "expressions": False,
4133        "query": False,
4134        "unnest": False,
4135        "field": False,
4136        "is_global": False,
4137    }
4138
4139
4140# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
4141class ForIn(Expression):
4142    arg_types = {"this": True, "expression": True}
4143
4144
4145class TimeUnit(Expression):
4146    """Automatically converts unit arg into a var."""
4147
4148    arg_types = {"unit": False}
4149
4150    UNABBREVIATED_UNIT_NAME = {
4151        "d": "day",
4152        "h": "hour",
4153        "m": "minute",
4154        "ms": "millisecond",
4155        "ns": "nanosecond",
4156        "q": "quarter",
4157        "s": "second",
4158        "us": "microsecond",
4159        "w": "week",
4160        "y": "year",
4161    }
4162
4163    VAR_LIKE = (Column, Literal, Var)
4164
4165    def __init__(self, **args):
4166        unit = args.get("unit")
4167        if isinstance(unit, self.VAR_LIKE):
4168            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4169        elif isinstance(unit, Week):
4170            unit.set("this", Var(this=unit.this.name))
4171
4172        super().__init__(**args)
4173
4174    @property
4175    def unit(self) -> t.Optional[Var]:
4176        return self.args.get("unit")
4177
4178
4179class IntervalOp(TimeUnit):
4180    arg_types = {"unit": True, "expression": True}
4181
4182    def interval(self):
4183        return Interval(
4184            this=self.expression.copy(),
4185            unit=self.unit.copy(),
4186        )
4187
4188
4189# https://www.oracletutorial.com/oracle-basics/oracle-interval/
4190# https://trino.io/docs/current/language/types.html#interval-day-to-second
4191# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
4192class IntervalSpan(DataType):
4193    arg_types = {"this": True, "expression": True}
4194
4195
4196class Interval(TimeUnit):
4197    arg_types = {"this": False, "unit": False}
4198
4199
4200class IgnoreNulls(Expression):
4201    pass
4202
4203
4204class RespectNulls(Expression):
4205    pass
4206
4207
4208# Functions
4209class Func(Condition):
4210    """
4211    The base class for all function expressions.
4212
4213    Attributes:
4214        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4215            treated as a variable length argument and the argument's value will be stored as a list.
4216        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4217            for this function expression. These values are used to map this node to a name during parsing
4218            as well as to provide the function's name during SQL string generation. By default the SQL
4219            name is set to the expression's class name transformed to snake case.
4220    """
4221
4222    is_var_len_args = False
4223
4224    @classmethod
4225    def from_arg_list(cls, args):
4226        if cls.is_var_len_args:
4227            all_arg_keys = list(cls.arg_types)
4228            # If this function supports variable length argument treat the last argument as such.
4229            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4230            num_non_var = len(non_var_len_arg_keys)
4231
4232            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4233            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4234        else:
4235            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4236
4237        return cls(**args_dict)
4238
4239    @classmethod
4240    def sql_names(cls):
4241        if cls is Func:
4242            raise NotImplementedError(
4243                "SQL name is only supported by concrete function implementations"
4244            )
4245        if "_sql_names" not in cls.__dict__:
4246            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4247        return cls._sql_names
4248
4249    @classmethod
4250    def sql_name(cls):
4251        return cls.sql_names()[0]
4252
4253    @classmethod
4254    def default_parser_mappings(cls):
4255        return {name: cls.from_arg_list for name in cls.sql_names()}
4256
4257
4258class AggFunc(Func):
4259    pass
4260
4261
4262class ParameterizedAgg(AggFunc):
4263    arg_types = {"this": True, "expressions": True, "params": True}
4264
4265
4266class Abs(Func):
4267    pass
4268
4269
4270class ArgMax(AggFunc):
4271    arg_types = {"this": True, "expression": True, "count": False}
4272    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
4273
4274
4275class ArgMin(AggFunc):
4276    arg_types = {"this": True, "expression": True, "count": False}
4277    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
4278
4279
4280class ApproxTopK(AggFunc):
4281    arg_types = {"this": True, "expression": False, "counters": False}
4282
4283
4284class Flatten(Func):
4285    pass
4286
4287
4288# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4289class Transform(Func):
4290    arg_types = {"this": True, "expression": True}
4291
4292
4293class Anonymous(Func):
4294    arg_types = {"this": True, "expressions": False}
4295    is_var_len_args = True
4296
4297
4298# https://docs.snowflake.com/en/sql-reference/functions/hll
4299# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4300class Hll(AggFunc):
4301    arg_types = {"this": True, "expressions": False}
4302    is_var_len_args = True
4303
4304
4305class ApproxDistinct(AggFunc):
4306    arg_types = {"this": True, "accuracy": False}
4307    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4308
4309
4310class Array(Func):
4311    arg_types = {"expressions": False}
4312    is_var_len_args = True
4313
4314
4315# https://docs.snowflake.com/en/sql-reference/functions/to_char
4316# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
4317class ToChar(Func):
4318    arg_types = {"this": True, "format": False, "nlsparam": False}
4319
4320
4321class GenerateSeries(Func):
4322    arg_types = {"start": True, "end": True, "step": False}
4323
4324
4325class ArrayAgg(AggFunc):
4326    pass
4327
4328
4329class ArrayUniqueAgg(AggFunc):
4330    pass
4331
4332
4333class ArrayAll(Func):
4334    arg_types = {"this": True, "expression": True}
4335
4336
4337class ArrayAny(Func):
4338    arg_types = {"this": True, "expression": True}
4339
4340
4341class ArrayConcat(Func):
4342    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4343    arg_types = {"this": True, "expressions": False}
4344    is_var_len_args = True
4345
4346
4347class ArrayContains(Binary, Func):
4348    pass
4349
4350
4351class ArrayContained(Binary):
4352    pass
4353
4354
4355class ArrayFilter(Func):
4356    arg_types = {"this": True, "expression": True}
4357    _sql_names = ["FILTER", "ARRAY_FILTER"]
4358
4359
4360class ArrayJoin(Func):
4361    arg_types = {"this": True, "expression": True, "null": False}
4362
4363
4364class ArraySize(Func):
4365    arg_types = {"this": True, "expression": False}
4366
4367
4368class ArraySort(Func):
4369    arg_types = {"this": True, "expression": False}
4370
4371
4372class ArraySum(Func):
4373    pass
4374
4375
4376class ArrayUnionAgg(AggFunc):
4377    pass
4378
4379
4380class Avg(AggFunc):
4381    pass
4382
4383
4384class AnyValue(AggFunc):
4385    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
4386
4387
4388class First(Func):
4389    arg_types = {"this": True, "ignore_nulls": False}
4390
4391
4392class Last(Func):
4393    arg_types = {"this": True, "ignore_nulls": False}
4394
4395
4396class Case(Func):
4397    arg_types = {"this": False, "ifs": True, "default": False}
4398
4399    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4400        instance = maybe_copy(self, copy)
4401        instance.append(
4402            "ifs",
4403            If(
4404                this=maybe_parse(condition, copy=copy, **opts),
4405                true=maybe_parse(then, copy=copy, **opts),
4406            ),
4407        )
4408        return instance
4409
4410    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4411        instance = maybe_copy(self, copy)
4412        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4413        return instance
4414
4415
4416class Cast(Func):
4417    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4418
4419    @property
4420    def name(self) -> str:
4421        return self.this.name
4422
4423    @property
4424    def to(self) -> DataType:
4425        return self.args["to"]
4426
4427    @property
4428    def output_name(self) -> str:
4429        return self.name
4430
4431    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4432        """
4433        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4434        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4435        array<int> != array<float>.
4436
4437        Args:
4438            dtypes: the data types to compare this Cast's DataType to.
4439
4440        Returns:
4441            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4442        """
4443        return self.to.is_type(*dtypes)
4444
4445
4446class TryCast(Cast):
4447    pass
4448
4449
4450class CastToStrType(Func):
4451    arg_types = {"this": True, "to": True}
4452
4453
4454class Collate(Binary, Func):
4455    pass
4456
4457
4458class Ceil(Func):
4459    arg_types = {"this": True, "decimals": False}
4460    _sql_names = ["CEIL", "CEILING"]
4461
4462
4463class Coalesce(Func):
4464    arg_types = {"this": True, "expressions": False}
4465    is_var_len_args = True
4466    _sql_names = ["COALESCE", "IFNULL", "NVL"]
4467
4468
4469class Chr(Func):
4470    arg_types = {"this": True, "charset": False, "expressions": False}
4471    is_var_len_args = True
4472    _sql_names = ["CHR", "CHAR"]
4473
4474
4475class Concat(Func):
4476    arg_types = {"expressions": True}
4477    is_var_len_args = True
4478
4479
4480class SafeConcat(Concat):
4481    pass
4482
4483
4484class ConcatWs(Concat):
4485    _sql_names = ["CONCAT_WS"]
4486
4487
4488class Count(AggFunc):
4489    arg_types = {"this": False, "expressions": False}
4490    is_var_len_args = True
4491
4492
4493class CountIf(AggFunc):
4494    pass
4495
4496
4497class CurrentDate(Func):
4498    arg_types = {"this": False}
4499
4500
4501class CurrentDatetime(Func):
4502    arg_types = {"this": False}
4503
4504
4505class CurrentTime(Func):
4506    arg_types = {"this": False}
4507
4508
4509class CurrentTimestamp(Func):
4510    arg_types = {"this": False}
4511
4512
4513class CurrentUser(Func):
4514    arg_types = {"this": False}
4515
4516
4517class DateAdd(Func, IntervalOp):
4518    arg_types = {"this": True, "expression": True, "unit": False}
4519
4520
4521class DateSub(Func, IntervalOp):
4522    arg_types = {"this": True, "expression": True, "unit": False}
4523
4524
4525class DateDiff(Func, TimeUnit):
4526    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4527    arg_types = {"this": True, "expression": True, "unit": False}
4528
4529
4530class DateTrunc(Func):
4531    arg_types = {"unit": True, "this": True, "zone": False}
4532
4533    @property
4534    def unit(self) -> Expression:
4535        return self.args["unit"]
4536
4537
4538class DatetimeAdd(Func, IntervalOp):
4539    arg_types = {"this": True, "expression": True, "unit": False}
4540
4541
4542class DatetimeSub(Func, IntervalOp):
4543    arg_types = {"this": True, "expression": True, "unit": False}
4544
4545
4546class DatetimeDiff(Func, TimeUnit):
4547    arg_types = {"this": True, "expression": True, "unit": False}
4548
4549
4550class DatetimeTrunc(Func, TimeUnit):
4551    arg_types = {"this": True, "unit": True, "zone": False}
4552
4553
4554class DayOfWeek(Func):
4555    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
4556
4557
4558class DayOfMonth(Func):
4559    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
4560
4561
4562class DayOfYear(Func):
4563    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
4564
4565
4566class ToDays(Func):
4567    pass
4568
4569
4570class WeekOfYear(Func):
4571    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
4572
4573
4574class MonthsBetween(Func):
4575    arg_types = {"this": True, "expression": True, "roundoff": False}
4576
4577
4578class LastDateOfMonth(Func):
4579    pass
4580
4581
4582class Extract(Func):
4583    arg_types = {"this": True, "expression": True}
4584
4585
4586class Timestamp(Func):
4587    arg_types = {"this": False, "expression": False}
4588
4589
4590class TimestampAdd(Func, TimeUnit):
4591    arg_types = {"this": True, "expression": True, "unit": False}
4592
4593
4594class TimestampSub(Func, TimeUnit):
4595    arg_types = {"this": True, "expression": True, "unit": False}
4596
4597
4598class TimestampDiff(Func, TimeUnit):
4599    arg_types = {"this": True, "expression": True, "unit": False}
4600
4601
4602class TimestampTrunc(Func, TimeUnit):
4603    arg_types = {"this": True, "unit": True, "zone": False}
4604
4605
4606class TimeAdd(Func, TimeUnit):
4607    arg_types = {"this": True, "expression": True, "unit": False}
4608
4609
4610class TimeSub(Func, TimeUnit):
4611    arg_types = {"this": True, "expression": True, "unit": False}
4612
4613
4614class TimeDiff(Func, TimeUnit):
4615    arg_types = {"this": True, "expression": True, "unit": False}
4616
4617
4618class TimeTrunc(Func, TimeUnit):
4619    arg_types = {"this": True, "unit": True, "zone": False}
4620
4621
4622class DateFromParts(Func):
4623    _sql_names = ["DATEFROMPARTS"]
4624    arg_types = {"year": True, "month": True, "day": True}
4625
4626
4627class DateStrToDate(Func):
4628    pass
4629
4630
4631class DateToDateStr(Func):
4632    pass
4633
4634
4635class DateToDi(Func):
4636    pass
4637
4638
4639# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
4640class Date(Func):
4641    arg_types = {"this": False, "zone": False, "expressions": False}
4642    is_var_len_args = True
4643
4644
4645class Day(Func):
4646    pass
4647
4648
4649class Decode(Func):
4650    arg_types = {"this": True, "charset": True, "replace": False}
4651
4652
4653class DiToDate(Func):
4654    pass
4655
4656
4657class Encode(Func):
4658    arg_types = {"this": True, "charset": True}
4659
4660
4661class Exp(Func):
4662    pass
4663
4664
4665# https://docs.snowflake.com/en/sql-reference/functions/flatten
4666class Explode(Func):
4667    arg_types = {"this": True, "expressions": False}
4668    is_var_len_args = True
4669
4670
4671class ExplodeOuter(Explode):
4672    pass
4673
4674
4675class Posexplode(Explode):
4676    pass
4677
4678
4679class PosexplodeOuter(Posexplode):
4680    pass
4681
4682
4683class Floor(Func):
4684    arg_types = {"this": True, "decimals": False}
4685
4686
4687class FromBase64(Func):
4688    pass
4689
4690
4691class ToBase64(Func):
4692    pass
4693
4694
4695class Greatest(Func):
4696    arg_types = {"this": True, "expressions": False}
4697    is_var_len_args = True
4698
4699
4700class GroupConcat(AggFunc):
4701    arg_types = {"this": True, "separator": False}
4702
4703
4704class Hex(Func):
4705    pass
4706
4707
4708class Xor(Connector, Func):
4709    arg_types = {"this": False, "expression": False, "expressions": False}
4710
4711
4712class If(Func):
4713    arg_types = {"this": True, "true": True, "false": False}
4714
4715
4716class Nullif(Func):
4717    arg_types = {"this": True, "expression": True}
4718
4719
4720class Initcap(Func):
4721    arg_types = {"this": True, "expression": False}
4722
4723
4724class IsNan(Func):
4725    _sql_names = ["IS_NAN", "ISNAN"]
4726
4727
4728class IsInf(Func):
4729    _sql_names = ["IS_INF", "ISINF"]
4730
4731
4732class FormatJson(Expression):
4733    pass
4734
4735
4736class JSONKeyValue(Expression):
4737    arg_types = {"this": True, "expression": True}
4738
4739
4740class JSONObject(Func):
4741    arg_types = {
4742        "expressions": False,
4743        "null_handling": False,
4744        "unique_keys": False,
4745        "return_type": False,
4746        "encoding": False,
4747    }
4748
4749
4750# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
4751class JSONArray(Func):
4752    arg_types = {
4753        "expressions": True,
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_ARRAYAGG.html
4761class JSONArrayAgg(Func):
4762    arg_types = {
4763        "this": True,
4764        "order": False,
4765        "null_handling": False,
4766        "return_type": False,
4767        "strict": False,
4768    }
4769
4770
4771# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4772# Note: parsing of JSON column definitions is currently incomplete.
4773class JSONColumnDef(Expression):
4774    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
4775
4776
4777class JSONSchema(Expression):
4778    arg_types = {"expressions": True}
4779
4780
4781# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4782class JSONTable(Func):
4783    arg_types = {
4784        "this": True,
4785        "schema": True,
4786        "path": False,
4787        "error_handling": False,
4788        "empty_handling": False,
4789    }
4790
4791
4792class OpenJSONColumnDef(Expression):
4793    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
4794
4795
4796class OpenJSON(Func):
4797    arg_types = {"this": True, "path": False, "expressions": False}
4798
4799
4800class JSONBContains(Binary):
4801    _sql_names = ["JSONB_CONTAINS"]
4802
4803
4804class JSONExtract(Binary, Func):
4805    _sql_names = ["JSON_EXTRACT"]
4806
4807
4808class JSONExtractScalar(JSONExtract):
4809    _sql_names = ["JSON_EXTRACT_SCALAR"]
4810
4811
4812class JSONBExtract(JSONExtract):
4813    _sql_names = ["JSONB_EXTRACT"]
4814
4815
4816class JSONBExtractScalar(JSONExtract):
4817    _sql_names = ["JSONB_EXTRACT_SCALAR"]
4818
4819
4820class JSONFormat(Func):
4821    arg_types = {"this": False, "options": False}
4822    _sql_names = ["JSON_FORMAT"]
4823
4824
4825# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
4826class JSONArrayContains(Binary, Predicate, Func):
4827    _sql_names = ["JSON_ARRAY_CONTAINS"]
4828
4829
4830class ParseJSON(Func):
4831    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4832    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4833    arg_types = {"this": True, "expressions": False}
4834    is_var_len_args = True
4835
4836
4837class Least(Func):
4838    arg_types = {"this": True, "expressions": False}
4839    is_var_len_args = True
4840
4841
4842class Left(Func):
4843    arg_types = {"this": True, "expression": True}
4844
4845
4846class Right(Func):
4847    arg_types = {"this": True, "expression": True}
4848
4849
4850class Length(Func):
4851    _sql_names = ["LENGTH", "LEN"]
4852
4853
4854class Levenshtein(Func):
4855    arg_types = {
4856        "this": True,
4857        "expression": False,
4858        "ins_cost": False,
4859        "del_cost": False,
4860        "sub_cost": False,
4861    }
4862
4863
4864class Ln(Func):
4865    pass
4866
4867
4868class Log(Func):
4869    arg_types = {"this": True, "expression": False}
4870
4871
4872class Log2(Func):
4873    pass
4874
4875
4876class Log10(Func):
4877    pass
4878
4879
4880class LogicalOr(AggFunc):
4881    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
4882
4883
4884class LogicalAnd(AggFunc):
4885    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
4886
4887
4888class Lower(Func):
4889    _sql_names = ["LOWER", "LCASE"]
4890
4891
4892class Map(Func):
4893    arg_types = {"keys": False, "values": False}
4894
4895    @property
4896    def keys(self) -> t.List[Expression]:
4897        keys = self.args.get("keys")
4898        return keys.expressions if keys else []
4899
4900    @property
4901    def values(self) -> t.List[Expression]:
4902        values = self.args.get("values")
4903        return values.expressions if values else []
4904
4905
4906class MapFromEntries(Func):
4907    pass
4908
4909
4910class StarMap(Func):
4911    pass
4912
4913
4914class VarMap(Func):
4915    arg_types = {"keys": True, "values": True}
4916    is_var_len_args = True
4917
4918    @property
4919    def keys(self) -> t.List[Expression]:
4920        return self.args["keys"].expressions
4921
4922    @property
4923    def values(self) -> t.List[Expression]:
4924        return self.args["values"].expressions
4925
4926
4927# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
4928class MatchAgainst(Func):
4929    arg_types = {"this": True, "expressions": True, "modifier": False}
4930
4931
4932class Max(AggFunc):
4933    arg_types = {"this": True, "expressions": False}
4934    is_var_len_args = True
4935
4936
4937class MD5(Func):
4938    _sql_names = ["MD5"]
4939
4940
4941# Represents the variant of the MD5 function that returns a binary value
4942class MD5Digest(Func):
4943    _sql_names = ["MD5_DIGEST"]
4944
4945
4946class Min(AggFunc):
4947    arg_types = {"this": True, "expressions": False}
4948    is_var_len_args = True
4949
4950
4951class Month(Func):
4952    pass
4953
4954
4955class Nvl2(Func):
4956    arg_types = {"this": True, "true": True, "false": False}
4957
4958
4959# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
4960class Predict(Func):
4961    arg_types = {"this": True, "expression": True, "params_struct": False}
4962
4963
4964class Pow(Binary, Func):
4965    _sql_names = ["POWER", "POW"]
4966
4967
4968class PercentileCont(AggFunc):
4969    arg_types = {"this": True, "expression": False}
4970
4971
4972class PercentileDisc(AggFunc):
4973    arg_types = {"this": True, "expression": False}
4974
4975
4976class Quantile(AggFunc):
4977    arg_types = {"this": True, "quantile": True}
4978
4979
4980class ApproxQuantile(Quantile):
4981    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
4982
4983
4984class RangeN(Func):
4985    arg_types = {"this": True, "expressions": True, "each": False}
4986
4987
4988class ReadCSV(Func):
4989    _sql_names = ["READ_CSV"]
4990    is_var_len_args = True
4991    arg_types = {"this": True, "expressions": False}
4992
4993
4994class Reduce(Func):
4995    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
4996
4997
4998class RegexpExtract(Func):
4999    arg_types = {
5000        "this": True,
5001        "expression": True,
5002        "position": False,
5003        "occurrence": False,
5004        "parameters": False,
5005        "group": False,
5006    }
5007
5008
5009class RegexpReplace(Func):
5010    arg_types = {
5011        "this": True,
5012        "expression": True,
5013        "replacement": True,
5014        "position": False,
5015        "occurrence": False,
5016        "parameters": False,
5017        "modifiers": False,
5018    }
5019
5020
5021class RegexpLike(Binary, Func):
5022    arg_types = {"this": True, "expression": True, "flag": False}
5023
5024
5025class RegexpILike(Binary, Func):
5026    arg_types = {"this": True, "expression": True, "flag": False}
5027
5028
5029# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5030# limit is the number of times a pattern is applied
5031class RegexpSplit(Func):
5032    arg_types = {"this": True, "expression": True, "limit": False}
5033
5034
5035class Repeat(Func):
5036    arg_types = {"this": True, "times": True}
5037
5038
5039class Round(Func):
5040    arg_types = {"this": True, "decimals": False}
5041
5042
5043class RowNumber(Func):
5044    arg_types: t.Dict[str, t.Any] = {}
5045
5046
5047class SafeDivide(Func):
5048    arg_types = {"this": True, "expression": True}
5049
5050
5051class SHA(Func):
5052    _sql_names = ["SHA", "SHA1"]
5053
5054
5055class SHA2(Func):
5056    _sql_names = ["SHA2"]
5057    arg_types = {"this": True, "length": False}
5058
5059
5060class SortArray(Func):
5061    arg_types = {"this": True, "asc": False}
5062
5063
5064class Split(Func):
5065    arg_types = {"this": True, "expression": True, "limit": False}
5066
5067
5068# Start may be omitted in the case of postgres
5069# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5070class Substring(Func):
5071    arg_types = {"this": True, "start": False, "length": False}
5072
5073
5074class StandardHash(Func):
5075    arg_types = {"this": True, "expression": False}
5076
5077
5078class StartsWith(Func):
5079    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5080    arg_types = {"this": True, "expression": True}
5081
5082
5083class StrPosition(Func):
5084    arg_types = {
5085        "this": True,
5086        "substr": True,
5087        "position": False,
5088        "instance": False,
5089    }
5090
5091
5092class StrToDate(Func):
5093    arg_types = {"this": True, "format": True}
5094
5095
5096class StrToTime(Func):
5097    arg_types = {"this": True, "format": True, "zone": False}
5098
5099
5100# Spark allows unix_timestamp()
5101# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5102class StrToUnix(Func):
5103    arg_types = {"this": False, "format": False}
5104
5105
5106# https://prestodb.io/docs/current/functions/string.html
5107# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5108class StrToMap(Func):
5109    arg_types = {
5110        "this": True,
5111        "pair_delim": False,
5112        "key_value_delim": False,
5113        "duplicate_resolution_callback": False,
5114    }
5115
5116
5117class NumberToStr(Func):
5118    arg_types = {"this": True, "format": True, "culture": False}
5119
5120
5121class FromBase(Func):
5122    arg_types = {"this": True, "expression": True}
5123
5124
5125class Struct(Func):
5126    arg_types = {"expressions": False}
5127    is_var_len_args = True
5128
5129
5130class StructExtract(Func):
5131    arg_types = {"this": True, "expression": True}
5132
5133
5134# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5135# https://docs.snowflake.com/en/sql-reference/functions/insert
5136class Stuff(Func):
5137    _sql_names = ["STUFF", "INSERT"]
5138    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5139
5140
5141class Sum(AggFunc):
5142    pass
5143
5144
5145class Sqrt(Func):
5146    pass
5147
5148
5149class Stddev(AggFunc):
5150    pass
5151
5152
5153class StddevPop(AggFunc):
5154    pass
5155
5156
5157class StddevSamp(AggFunc):
5158    pass
5159
5160
5161class TimeToStr(Func):
5162    arg_types = {"this": True, "format": True, "culture": False}
5163
5164
5165class TimeToTimeStr(Func):
5166    pass
5167
5168
5169class TimeToUnix(Func):
5170    pass
5171
5172
5173class TimeStrToDate(Func):
5174    pass
5175
5176
5177class TimeStrToTime(Func):
5178    pass
5179
5180
5181class TimeStrToUnix(Func):
5182    pass
5183
5184
5185class Trim(Func):
5186    arg_types = {
5187        "this": True,
5188        "expression": False,
5189        "position": False,
5190        "collation": False,
5191    }
5192
5193
5194class TsOrDsAdd(Func, TimeUnit):
5195    # return_type is used to correctly cast the arguments of this expression when transpiling it
5196    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5197
5198    @property
5199    def return_type(self) -> DataType:
5200        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5201
5202
5203class TsOrDsDiff(Func, TimeUnit):
5204    arg_types = {"this": True, "expression": True, "unit": False}
5205
5206
5207class TsOrDsToDateStr(Func):
5208    pass
5209
5210
5211class TsOrDsToDate(Func):
5212    arg_types = {"this": True, "format": False}
5213
5214
5215class TsOrDiToDi(Func):
5216    pass
5217
5218
5219class Unhex(Func):
5220    pass
5221
5222
5223class UnixToStr(Func):
5224    arg_types = {"this": True, "format": False}
5225
5226
5227# https://prestodb.io/docs/current/functions/datetime.html
5228# presto has weird zone/hours/minutes
5229class UnixToTime(Func):
5230    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5231
5232    SECONDS = Literal.string("seconds")
5233    MILLIS = Literal.string("millis")
5234    MICROS = Literal.string("micros")
5235    NANOS = Literal.string("nanos")
5236
5237
5238class UnixToTimeStr(Func):
5239    pass
5240
5241
5242class Upper(Func):
5243    _sql_names = ["UPPER", "UCASE"]
5244
5245
5246class Variance(AggFunc):
5247    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5248
5249
5250class VariancePop(AggFunc):
5251    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5252
5253
5254class Week(Func):
5255    arg_types = {"this": True, "mode": False}
5256
5257
5258class XMLTable(Func):
5259    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5260
5261
5262class Year(Func):
5263    pass
5264
5265
5266class Use(Expression):
5267    arg_types = {"this": True, "kind": False}
5268
5269
5270class Merge(Expression):
5271    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
5272
5273
5274class When(Func):
5275    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5276
5277
5278# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5279# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5280class NextValueFor(Func):
5281    arg_types = {"this": True, "order": False}
5282
5283
5284def _norm_arg(arg):
5285    return arg.lower() if type(arg) is str else arg
5286
5287
5288ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5289
5290
5291# Helpers
5292@t.overload
5293def maybe_parse(
5294    sql_or_expression: ExpOrStr,
5295    *,
5296    into: t.Type[E],
5297    dialect: DialectType = None,
5298    prefix: t.Optional[str] = None,
5299    copy: bool = False,
5300    **opts,
5301) -> E:
5302    ...
5303
5304
5305@t.overload
5306def maybe_parse(
5307    sql_or_expression: str | E,
5308    *,
5309    into: t.Optional[IntoType] = None,
5310    dialect: DialectType = None,
5311    prefix: t.Optional[str] = None,
5312    copy: bool = False,
5313    **opts,
5314) -> E:
5315    ...
5316
5317
5318def maybe_parse(
5319    sql_or_expression: ExpOrStr,
5320    *,
5321    into: t.Optional[IntoType] = None,
5322    dialect: DialectType = None,
5323    prefix: t.Optional[str] = None,
5324    copy: bool = False,
5325    **opts,
5326) -> Expression:
5327    """Gracefully handle a possible string or expression.
5328
5329    Example:
5330        >>> maybe_parse("1")
5331        (LITERAL this: 1, is_string: False)
5332        >>> maybe_parse(to_identifier("x"))
5333        (IDENTIFIER this: x, quoted: False)
5334
5335    Args:
5336        sql_or_expression: the SQL code string or an expression
5337        into: the SQLGlot Expression to parse into
5338        dialect: the dialect used to parse the input expressions (in the case that an
5339            input expression is a SQL string).
5340        prefix: a string to prefix the sql with before it gets parsed
5341            (automatically includes a space)
5342        copy: whether or not to copy the expression.
5343        **opts: other options to use to parse the input expressions (again, in the case
5344            that an input expression is a SQL string).
5345
5346    Returns:
5347        Expression: the parsed or given expression.
5348    """
5349    if isinstance(sql_or_expression, Expression):
5350        if copy:
5351            return sql_or_expression.copy()
5352        return sql_or_expression
5353
5354    if sql_or_expression is None:
5355        raise ParseError(f"SQL cannot be None")
5356
5357    import sqlglot
5358
5359    sql = str(sql_or_expression)
5360    if prefix:
5361        sql = f"{prefix} {sql}"
5362
5363    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5364
5365
5366@t.overload
5367def maybe_copy(instance: None, copy: bool = True) -> None:
5368    ...
5369
5370
5371@t.overload
5372def maybe_copy(instance: E, copy: bool = True) -> E:
5373    ...
5374
5375
5376def maybe_copy(instance, copy=True):
5377    return instance.copy() if copy and instance else instance
5378
5379
5380def _is_wrong_expression(expression, into):
5381    return isinstance(expression, Expression) and not isinstance(expression, into)
5382
5383
5384def _apply_builder(
5385    expression,
5386    instance,
5387    arg,
5388    copy=True,
5389    prefix=None,
5390    into=None,
5391    dialect=None,
5392    into_arg="this",
5393    **opts,
5394):
5395    if _is_wrong_expression(expression, into):
5396        expression = into(**{into_arg: expression})
5397    instance = maybe_copy(instance, copy)
5398    expression = maybe_parse(
5399        sql_or_expression=expression,
5400        prefix=prefix,
5401        into=into,
5402        dialect=dialect,
5403        **opts,
5404    )
5405    instance.set(arg, expression)
5406    return instance
5407
5408
5409def _apply_child_list_builder(
5410    *expressions,
5411    instance,
5412    arg,
5413    append=True,
5414    copy=True,
5415    prefix=None,
5416    into=None,
5417    dialect=None,
5418    properties=None,
5419    **opts,
5420):
5421    instance = maybe_copy(instance, copy)
5422    parsed = []
5423    for expression in expressions:
5424        if expression is not None:
5425            if _is_wrong_expression(expression, into):
5426                expression = into(expressions=[expression])
5427
5428            expression = maybe_parse(
5429                expression,
5430                into=into,
5431                dialect=dialect,
5432                prefix=prefix,
5433                **opts,
5434            )
5435            parsed.extend(expression.expressions)
5436
5437    existing = instance.args.get(arg)
5438    if append and existing:
5439        parsed = existing.expressions + parsed
5440
5441    child = into(expressions=parsed)
5442    for k, v in (properties or {}).items():
5443        child.set(k, v)
5444    instance.set(arg, child)
5445
5446    return instance
5447
5448
5449def _apply_list_builder(
5450    *expressions,
5451    instance,
5452    arg,
5453    append=True,
5454    copy=True,
5455    prefix=None,
5456    into=None,
5457    dialect=None,
5458    **opts,
5459):
5460    inst = maybe_copy(instance, copy)
5461
5462    expressions = [
5463        maybe_parse(
5464            sql_or_expression=expression,
5465            into=into,
5466            prefix=prefix,
5467            dialect=dialect,
5468            **opts,
5469        )
5470        for expression in expressions
5471        if expression is not None
5472    ]
5473
5474    existing_expressions = inst.args.get(arg)
5475    if append and existing_expressions:
5476        expressions = existing_expressions + expressions
5477
5478    inst.set(arg, expressions)
5479    return inst
5480
5481
5482def _apply_conjunction_builder(
5483    *expressions,
5484    instance,
5485    arg,
5486    into=None,
5487    append=True,
5488    copy=True,
5489    dialect=None,
5490    **opts,
5491):
5492    expressions = [exp for exp in expressions if exp is not None and exp != ""]
5493    if not expressions:
5494        return instance
5495
5496    inst = maybe_copy(instance, copy)
5497
5498    existing = inst.args.get(arg)
5499    if append and existing is not None:
5500        expressions = [existing.this if into else existing] + list(expressions)
5501
5502    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
5503
5504    inst.set(arg, into(this=node) if into else node)
5505    return inst
5506
5507
5508def _apply_cte_builder(
5509    instance: E,
5510    alias: ExpOrStr,
5511    as_: ExpOrStr,
5512    recursive: t.Optional[bool] = None,
5513    append: bool = True,
5514    dialect: DialectType = None,
5515    copy: bool = True,
5516    **opts,
5517) -> E:
5518    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
5519    as_expression = maybe_parse(as_, dialect=dialect, **opts)
5520    cte = CTE(this=as_expression, alias=alias_expression)
5521    return _apply_child_list_builder(
5522        cte,
5523        instance=instance,
5524        arg="with",
5525        append=append,
5526        copy=copy,
5527        into=With,
5528        properties={"recursive": recursive or False},
5529    )
5530
5531
5532def _combine(
5533    expressions: t.Sequence[t.Optional[ExpOrStr]],
5534    operator: t.Type[Connector],
5535    dialect: DialectType = None,
5536    copy: bool = True,
5537    **opts,
5538) -> Expression:
5539    conditions = [
5540        condition(expression, dialect=dialect, copy=copy, **opts)
5541        for expression in expressions
5542        if expression is not None
5543    ]
5544
5545    this, *rest = conditions
5546    if rest:
5547        this = _wrap(this, Connector)
5548    for expression in rest:
5549        this = operator(this=this, expression=_wrap(expression, Connector))
5550
5551    return this
5552
5553
5554def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
5555    return Paren(this=expression) if isinstance(expression, kind) else expression
5556
5557
5558def union(
5559    left: ExpOrStr,
5560    right: ExpOrStr,
5561    distinct: bool = True,
5562    dialect: DialectType = None,
5563    copy: bool = True,
5564    **opts,
5565) -> Union:
5566    """
5567    Initializes a syntax tree from one UNION expression.
5568
5569    Example:
5570        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5571        'SELECT * FROM foo UNION SELECT * FROM bla'
5572
5573    Args:
5574        left: the SQL code string corresponding to the left-hand side.
5575            If an `Expression` instance is passed, it will be used as-is.
5576        right: the SQL code string corresponding to the right-hand side.
5577            If an `Expression` instance is passed, it will be used as-is.
5578        distinct: set the DISTINCT flag if and only if this is true.
5579        dialect: the dialect used to parse the input expression.
5580        copy: whether or not to copy the expression.
5581        opts: other options to use to parse the input expressions.
5582
5583    Returns:
5584        The new Union instance.
5585    """
5586    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5587    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5588
5589    return Union(this=left, expression=right, distinct=distinct)
5590
5591
5592def intersect(
5593    left: ExpOrStr,
5594    right: ExpOrStr,
5595    distinct: bool = True,
5596    dialect: DialectType = None,
5597    copy: bool = True,
5598    **opts,
5599) -> Intersect:
5600    """
5601    Initializes a syntax tree from one INTERSECT expression.
5602
5603    Example:
5604        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5605        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5606
5607    Args:
5608        left: the SQL code string corresponding to the left-hand side.
5609            If an `Expression` instance is passed, it will be used as-is.
5610        right: the SQL code string corresponding to the right-hand side.
5611            If an `Expression` instance is passed, it will be used as-is.
5612        distinct: set the DISTINCT flag if and only if this is true.
5613        dialect: the dialect used to parse the input expression.
5614        copy: whether or not to copy the expression.
5615        opts: other options to use to parse the input expressions.
5616
5617    Returns:
5618        The new Intersect instance.
5619    """
5620    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5621    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5622
5623    return Intersect(this=left, expression=right, distinct=distinct)
5624
5625
5626def except_(
5627    left: ExpOrStr,
5628    right: ExpOrStr,
5629    distinct: bool = True,
5630    dialect: DialectType = None,
5631    copy: bool = True,
5632    **opts,
5633) -> Except:
5634    """
5635    Initializes a syntax tree from one EXCEPT expression.
5636
5637    Example:
5638        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5639        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5640
5641    Args:
5642        left: the SQL code string corresponding to the left-hand side.
5643            If an `Expression` instance is passed, it will be used as-is.
5644        right: the SQL code string corresponding to the right-hand side.
5645            If an `Expression` instance is passed, it will be used as-is.
5646        distinct: set the DISTINCT flag if and only if this is true.
5647        dialect: the dialect used to parse the input expression.
5648        copy: whether or not to copy the expression.
5649        opts: other options to use to parse the input expressions.
5650
5651    Returns:
5652        The new Except instance.
5653    """
5654    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5655    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5656
5657    return Except(this=left, expression=right, distinct=distinct)
5658
5659
5660def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5661    """
5662    Initializes a syntax tree from one or multiple SELECT expressions.
5663
5664    Example:
5665        >>> select("col1", "col2").from_("tbl").sql()
5666        'SELECT col1, col2 FROM tbl'
5667
5668    Args:
5669        *expressions: the SQL code string to parse as the expressions of a
5670            SELECT statement. If an Expression instance is passed, this is used as-is.
5671        dialect: the dialect used to parse the input expressions (in the case that an
5672            input expression is a SQL string).
5673        **opts: other options to use to parse the input expressions (again, in the case
5674            that an input expression is a SQL string).
5675
5676    Returns:
5677        Select: the syntax tree for the SELECT statement.
5678    """
5679    return Select().select(*expressions, dialect=dialect, **opts)
5680
5681
5682def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5683    """
5684    Initializes a syntax tree from a FROM expression.
5685
5686    Example:
5687        >>> from_("tbl").select("col1", "col2").sql()
5688        'SELECT col1, col2 FROM tbl'
5689
5690    Args:
5691        *expression: the SQL code string to parse as the FROM expressions of a
5692            SELECT statement. If an Expression instance is passed, this is used as-is.
5693        dialect: the dialect used to parse the input expression (in the case that the
5694            input expression is a SQL string).
5695        **opts: other options to use to parse the input expressions (again, in the case
5696            that the input expression is a SQL string).
5697
5698    Returns:
5699        Select: the syntax tree for the SELECT statement.
5700    """
5701    return Select().from_(expression, dialect=dialect, **opts)
5702
5703
5704def update(
5705    table: str | Table,
5706    properties: dict,
5707    where: t.Optional[ExpOrStr] = None,
5708    from_: t.Optional[ExpOrStr] = None,
5709    dialect: DialectType = None,
5710    **opts,
5711) -> Update:
5712    """
5713    Creates an update statement.
5714
5715    Example:
5716        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5717        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5718
5719    Args:
5720        *properties: dictionary of properties to set which are
5721            auto converted to sql objects eg None -> NULL
5722        where: sql conditional parsed into a WHERE statement
5723        from_: sql statement parsed into a FROM statement
5724        dialect: the dialect used to parse the input expressions.
5725        **opts: other options to use to parse the input expressions.
5726
5727    Returns:
5728        Update: the syntax tree for the UPDATE statement.
5729    """
5730    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5731    update_expr.set(
5732        "expressions",
5733        [
5734            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5735            for k, v in properties.items()
5736        ],
5737    )
5738    if from_:
5739        update_expr.set(
5740            "from",
5741            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5742        )
5743    if isinstance(where, Condition):
5744        where = Where(this=where)
5745    if where:
5746        update_expr.set(
5747            "where",
5748            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5749        )
5750    return update_expr
5751
5752
5753def delete(
5754    table: ExpOrStr,
5755    where: t.Optional[ExpOrStr] = None,
5756    returning: t.Optional[ExpOrStr] = None,
5757    dialect: DialectType = None,
5758    **opts,
5759) -> Delete:
5760    """
5761    Builds a delete statement.
5762
5763    Example:
5764        >>> delete("my_table", where="id > 1").sql()
5765        'DELETE FROM my_table WHERE id > 1'
5766
5767    Args:
5768        where: sql conditional parsed into a WHERE statement
5769        returning: sql conditional parsed into a RETURNING statement
5770        dialect: the dialect used to parse the input expressions.
5771        **opts: other options to use to parse the input expressions.
5772
5773    Returns:
5774        Delete: the syntax tree for the DELETE statement.
5775    """
5776    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5777    if where:
5778        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5779    if returning:
5780        delete_expr = t.cast(
5781            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5782        )
5783    return delete_expr
5784
5785
5786def insert(
5787    expression: ExpOrStr,
5788    into: ExpOrStr,
5789    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5790    overwrite: t.Optional[bool] = None,
5791    returning: t.Optional[ExpOrStr] = None,
5792    dialect: DialectType = None,
5793    copy: bool = True,
5794    **opts,
5795) -> Insert:
5796    """
5797    Builds an INSERT statement.
5798
5799    Example:
5800        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5801        'INSERT INTO tbl VALUES (1, 2, 3)'
5802
5803    Args:
5804        expression: the sql string or expression of the INSERT statement
5805        into: the tbl to insert data to.
5806        columns: optionally the table's column names.
5807        overwrite: whether to INSERT OVERWRITE or not.
5808        returning: sql conditional parsed into a RETURNING statement
5809        dialect: the dialect used to parse the input expressions.
5810        copy: whether or not to copy the expression.
5811        **opts: other options to use to parse the input expressions.
5812
5813    Returns:
5814        Insert: the syntax tree for the INSERT statement.
5815    """
5816    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5817    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5818
5819    if columns:
5820        this = _apply_list_builder(
5821            *columns,
5822            instance=Schema(this=this),
5823            arg="expressions",
5824            into=Identifier,
5825            copy=False,
5826            dialect=dialect,
5827            **opts,
5828        )
5829
5830    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5831
5832    if returning:
5833        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5834
5835    return insert
5836
5837
5838def condition(
5839    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5840) -> Condition:
5841    """
5842    Initialize a logical condition expression.
5843
5844    Example:
5845        >>> condition("x=1").sql()
5846        'x = 1'
5847
5848        This is helpful for composing larger logical syntax trees:
5849        >>> where = condition("x=1")
5850        >>> where = where.and_("y=1")
5851        >>> Select().from_("tbl").select("*").where(where).sql()
5852        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5853
5854    Args:
5855        *expression: the SQL code string to parse.
5856            If an Expression instance is passed, this is used as-is.
5857        dialect: the dialect used to parse the input expression (in the case that the
5858            input expression is a SQL string).
5859        copy: Whether or not to copy `expression` (only applies to expressions).
5860        **opts: other options to use to parse the input expressions (again, in the case
5861            that the input expression is a SQL string).
5862
5863    Returns:
5864        The new Condition instance
5865    """
5866    return maybe_parse(
5867        expression,
5868        into=Condition,
5869        dialect=dialect,
5870        copy=copy,
5871        **opts,
5872    )
5873
5874
5875def and_(
5876    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5877) -> Condition:
5878    """
5879    Combine multiple conditions with an AND logical operator.
5880
5881    Example:
5882        >>> and_("x=1", and_("y=1", "z=1")).sql()
5883        'x = 1 AND (y = 1 AND z = 1)'
5884
5885    Args:
5886        *expressions: the SQL code strings to parse.
5887            If an Expression instance is passed, this is used as-is.
5888        dialect: the dialect used to parse the input expression.
5889        copy: whether or not to copy `expressions` (only applies to Expressions).
5890        **opts: other options to use to parse the input expressions.
5891
5892    Returns:
5893        And: the new condition
5894    """
5895    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
5896
5897
5898def or_(
5899    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5900) -> Condition:
5901    """
5902    Combine multiple conditions with an OR logical operator.
5903
5904    Example:
5905        >>> or_("x=1", or_("y=1", "z=1")).sql()
5906        'x = 1 OR (y = 1 OR z = 1)'
5907
5908    Args:
5909        *expressions: the SQL code strings to parse.
5910            If an Expression instance is passed, this is used as-is.
5911        dialect: the dialect used to parse the input expression.
5912        copy: whether or not to copy `expressions` (only applies to Expressions).
5913        **opts: other options to use to parse the input expressions.
5914
5915    Returns:
5916        Or: the new condition
5917    """
5918    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
5919
5920
5921def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5922    """
5923    Wrap a condition with a NOT operator.
5924
5925    Example:
5926        >>> not_("this_suit='black'").sql()
5927        "NOT this_suit = 'black'"
5928
5929    Args:
5930        expression: the SQL code string to parse.
5931            If an Expression instance is passed, this is used as-is.
5932        dialect: the dialect used to parse the input expression.
5933        copy: whether to copy the expression or not.
5934        **opts: other options to use to parse the input expressions.
5935
5936    Returns:
5937        The new condition.
5938    """
5939    this = condition(
5940        expression,
5941        dialect=dialect,
5942        copy=copy,
5943        **opts,
5944    )
5945    return Not(this=_wrap(this, Connector))
5946
5947
5948def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5949    """
5950    Wrap an expression in parentheses.
5951
5952    Example:
5953        >>> paren("5 + 3").sql()
5954        '(5 + 3)'
5955
5956    Args:
5957        expression: the SQL code string to parse.
5958            If an Expression instance is passed, this is used as-is.
5959        copy: whether to copy the expression or not.
5960
5961    Returns:
5962        The wrapped expression.
5963    """
5964    return Paren(this=maybe_parse(expression, copy=copy))
5965
5966
5967SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$")
5968
5969
5970@t.overload
5971def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None:
5972    ...
5973
5974
5975@t.overload
5976def to_identifier(
5977    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
5978) -> Identifier:
5979    ...
5980
5981
5982def to_identifier(name, quoted=None, copy=True):
5983    """Builds an identifier.
5984
5985    Args:
5986        name: The name to turn into an identifier.
5987        quoted: Whether or not force quote the identifier.
5988        copy: Whether or not to copy name if it's an Identifier.
5989
5990    Returns:
5991        The identifier ast node.
5992    """
5993
5994    if name is None:
5995        return None
5996
5997    if isinstance(name, Identifier):
5998        identifier = maybe_copy(name, copy)
5999    elif isinstance(name, str):
6000        identifier = Identifier(
6001            this=name,
6002            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6003        )
6004    else:
6005        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6006    return identifier
6007
6008
6009def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6010    """
6011    Parses a given string into an identifier.
6012
6013    Args:
6014        name: The name to parse into an identifier.
6015        dialect: The dialect to parse against.
6016
6017    Returns:
6018        The identifier ast node.
6019    """
6020    try:
6021        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6022    except ParseError:
6023        expression = to_identifier(name)
6024
6025    return expression
6026
6027
6028INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6029
6030
6031def to_interval(interval: str | Literal) -> Interval:
6032    """Builds an interval expression from a string like '1 day' or '5 months'."""
6033    if isinstance(interval, Literal):
6034        if not interval.is_string:
6035            raise ValueError("Invalid interval string.")
6036
6037        interval = interval.this
6038
6039    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6040
6041    if not interval_parts:
6042        raise ValueError("Invalid interval string.")
6043
6044    return Interval(
6045        this=Literal.string(interval_parts.group(1)),
6046        unit=Var(this=interval_parts.group(2)),
6047    )
6048
6049
6050@t.overload
6051def to_table(sql_path: str | Table, **kwargs) -> Table:
6052    ...
6053
6054
6055@t.overload
6056def to_table(sql_path: None, **kwargs) -> None:
6057    ...
6058
6059
6060def to_table(
6061    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6062) -> t.Optional[Table]:
6063    """
6064    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6065    If a table is passed in then that table is returned.
6066
6067    Args:
6068        sql_path: a `[catalog].[schema].[table]` string.
6069        dialect: the source dialect according to which the table name will be parsed.
6070        copy: Whether or not to copy a table if it is passed in.
6071        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6072
6073    Returns:
6074        A table expression.
6075    """
6076    if sql_path is None or isinstance(sql_path, Table):
6077        return maybe_copy(sql_path, copy=copy)
6078    if not isinstance(sql_path, str):
6079        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6080
6081    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6082    if table:
6083        for k, v in kwargs.items():
6084            table.set(k, v)
6085
6086    return table
6087
6088
6089def to_column(sql_path: str | Column, **kwargs) -> Column:
6090    """
6091    Create a column from a `[table].[column]` sql path. Schema is optional.
6092
6093    If a column is passed in then that column is returned.
6094
6095    Args:
6096        sql_path: `[table].[column]` string
6097    Returns:
6098        Table: A column expression
6099    """
6100    if sql_path is None or isinstance(sql_path, Column):
6101        return sql_path
6102    if not isinstance(sql_path, str):
6103        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6104    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
6105
6106
6107def alias_(
6108    expression: ExpOrStr,
6109    alias: str | Identifier,
6110    table: bool | t.Sequence[str | Identifier] = False,
6111    quoted: t.Optional[bool] = None,
6112    dialect: DialectType = None,
6113    copy: bool = True,
6114    **opts,
6115):
6116    """Create an Alias expression.
6117
6118    Example:
6119        >>> alias_('foo', 'bar').sql()
6120        'foo AS bar'
6121
6122        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6123        '(SELECT 1, 2) AS bar(a, b)'
6124
6125    Args:
6126        expression: the SQL code strings to parse.
6127            If an Expression instance is passed, this is used as-is.
6128        alias: the alias name to use. If the name has
6129            special characters it is quoted.
6130        table: Whether or not to create a table alias, can also be a list of columns.
6131        quoted: whether or not to quote the alias
6132        dialect: the dialect used to parse the input expression.
6133        copy: Whether or not to copy the expression.
6134        **opts: other options to use to parse the input expressions.
6135
6136    Returns:
6137        Alias: the aliased expression
6138    """
6139    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6140    alias = to_identifier(alias, quoted=quoted)
6141
6142    if table:
6143        table_alias = TableAlias(this=alias)
6144        exp.set("alias", table_alias)
6145
6146        if not isinstance(table, bool):
6147            for column in table:
6148                table_alias.append("columns", to_identifier(column, quoted=quoted))
6149
6150        return exp
6151
6152    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6153    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6154    # for the complete Window expression.
6155    #
6156    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6157
6158    if "alias" in exp.arg_types and not isinstance(exp, Window):
6159        exp.set("alias", alias)
6160        return exp
6161    return Alias(this=exp, alias=alias)
6162
6163
6164def subquery(
6165    expression: ExpOrStr,
6166    alias: t.Optional[Identifier | str] = None,
6167    dialect: DialectType = None,
6168    **opts,
6169) -> Select:
6170    """
6171    Build a subquery expression.
6172
6173    Example:
6174        >>> subquery('select x from tbl', 'bar').select('x').sql()
6175        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6176
6177    Args:
6178        expression: the SQL code strings to parse.
6179            If an Expression instance is passed, this is used as-is.
6180        alias: the alias name to use.
6181        dialect: the dialect used to parse the input expression.
6182        **opts: other options to use to parse the input expressions.
6183
6184    Returns:
6185        A new Select instance with the subquery expression included.
6186    """
6187
6188    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6189    return Select().from_(expression, dialect=dialect, **opts)
6190
6191
6192def column(
6193    col: str | Identifier,
6194    table: t.Optional[str | Identifier] = None,
6195    db: t.Optional[str | Identifier] = None,
6196    catalog: t.Optional[str | Identifier] = None,
6197    quoted: t.Optional[bool] = None,
6198) -> Column:
6199    """
6200    Build a Column.
6201
6202    Args:
6203        col: Column name.
6204        table: Table name.
6205        db: Database name.
6206        catalog: Catalog name.
6207        quoted: Whether to force quotes on the column's identifiers.
6208
6209    Returns:
6210        The new Column instance.
6211    """
6212    return Column(
6213        this=to_identifier(col, quoted=quoted),
6214        table=to_identifier(table, quoted=quoted),
6215        db=to_identifier(db, quoted=quoted),
6216        catalog=to_identifier(catalog, quoted=quoted),
6217    )
6218
6219
6220def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6221    """Cast an expression to a data type.
6222
6223    Example:
6224        >>> cast('x + 1', 'int').sql()
6225        'CAST(x + 1 AS INT)'
6226
6227    Args:
6228        expression: The expression to cast.
6229        to: The datatype to cast to.
6230
6231    Returns:
6232        The new Cast instance.
6233    """
6234    expression = maybe_parse(expression, **opts)
6235    data_type = DataType.build(to, **opts)
6236    expression = Cast(this=expression, to=data_type)
6237    expression.type = data_type
6238    return expression
6239
6240
6241def table_(
6242    table: Identifier | str,
6243    db: t.Optional[Identifier | str] = None,
6244    catalog: t.Optional[Identifier | str] = None,
6245    quoted: t.Optional[bool] = None,
6246    alias: t.Optional[Identifier | str] = None,
6247) -> Table:
6248    """Build a Table.
6249
6250    Args:
6251        table: Table name.
6252        db: Database name.
6253        catalog: Catalog name.
6254        quote: Whether to force quotes on the table's identifiers.
6255        alias: Table's alias.
6256
6257    Returns:
6258        The new Table instance.
6259    """
6260    return Table(
6261        this=to_identifier(table, quoted=quoted) if table else None,
6262        db=to_identifier(db, quoted=quoted) if db else None,
6263        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6264        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6265    )
6266
6267
6268def values(
6269    values: t.Iterable[t.Tuple[t.Any, ...]],
6270    alias: t.Optional[str] = None,
6271    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6272) -> Values:
6273    """Build VALUES statement.
6274
6275    Example:
6276        >>> values([(1, '2')]).sql()
6277        "VALUES (1, '2')"
6278
6279    Args:
6280        values: values statements that will be converted to SQL
6281        alias: optional alias
6282        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6283         If either are provided then an alias is also required.
6284
6285    Returns:
6286        Values: the Values expression object
6287    """
6288    if columns and not alias:
6289        raise ValueError("Alias is required when providing columns")
6290
6291    return Values(
6292        expressions=[convert(tup) for tup in values],
6293        alias=(
6294            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6295            if columns
6296            else (TableAlias(this=to_identifier(alias)) if alias else None)
6297        ),
6298    )
6299
6300
6301def var(name: t.Optional[ExpOrStr]) -> Var:
6302    """Build a SQL variable.
6303
6304    Example:
6305        >>> repr(var('x'))
6306        '(VAR this: x)'
6307
6308        >>> repr(var(column('x', table='y')))
6309        '(VAR this: x)'
6310
6311    Args:
6312        name: The name of the var or an expression who's name will become the var.
6313
6314    Returns:
6315        The new variable node.
6316    """
6317    if not name:
6318        raise ValueError("Cannot convert empty name into var.")
6319
6320    if isinstance(name, Expression):
6321        name = name.name
6322    return Var(this=name)
6323
6324
6325def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6326    """Build ALTER TABLE... RENAME... expression
6327
6328    Args:
6329        old_name: The old name of the table
6330        new_name: The new name of the table
6331
6332    Returns:
6333        Alter table expression
6334    """
6335    old_table = to_table(old_name)
6336    new_table = to_table(new_name)
6337    return AlterTable(
6338        this=old_table,
6339        actions=[
6340            RenameTable(this=new_table),
6341        ],
6342    )
6343
6344
6345def convert(value: t.Any, copy: bool = False) -> Expression:
6346    """Convert a python value into an expression object.
6347
6348    Raises an error if a conversion is not possible.
6349
6350    Args:
6351        value: A python object.
6352        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6353
6354    Returns:
6355        Expression: the equivalent expression object.
6356    """
6357    if isinstance(value, Expression):
6358        return maybe_copy(value, copy)
6359    if isinstance(value, str):
6360        return Literal.string(value)
6361    if isinstance(value, bool):
6362        return Boolean(this=value)
6363    if value is None or (isinstance(value, float) and math.isnan(value)):
6364        return NULL
6365    if isinstance(value, numbers.Number):
6366        return Literal.number(value)
6367    if isinstance(value, datetime.datetime):
6368        datetime_literal = Literal.string(
6369            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6370        )
6371        return TimeStrToTime(this=datetime_literal)
6372    if isinstance(value, datetime.date):
6373        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6374        return DateStrToDate(this=date_literal)
6375    if isinstance(value, tuple):
6376        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6377    if isinstance(value, list):
6378        return Array(expressions=[convert(v, copy=copy) for v in value])
6379    if isinstance(value, dict):
6380        return Map(
6381            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6382            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6383        )
6384    raise ValueError(f"Cannot convert {value}")
6385
6386
6387def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6388    """
6389    Replace children of an expression with the result of a lambda fun(child) -> exp.
6390    """
6391    for k, v in expression.args.items():
6392        is_list_arg = type(v) is list
6393
6394        child_nodes = v if is_list_arg else [v]
6395        new_child_nodes = []
6396
6397        for cn in child_nodes:
6398            if isinstance(cn, Expression):
6399                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6400                    new_child_nodes.append(child_node)
6401                    child_node.parent = expression
6402                    child_node.arg_key = k
6403            else:
6404                new_child_nodes.append(cn)
6405
6406        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
6407
6408
6409def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6410    """
6411    Return all table names referenced through columns in an expression.
6412
6413    Example:
6414        >>> import sqlglot
6415        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6416        ['a', 'c']
6417
6418    Args:
6419        expression: expression to find table names.
6420        exclude: a table name to exclude
6421
6422    Returns:
6423        A list of unique names.
6424    """
6425    return {
6426        table
6427        for table in (column.table for column in expression.find_all(Column))
6428        if table and table != exclude
6429    }
6430
6431
6432def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6433    """Get the full name of a table as a string.
6434
6435    Args:
6436        table: Table expression node or string.
6437        dialect: The dialect to generate the table name for.
6438        identify: Determines when an identifier should be quoted. Possible values are:
6439            False (default): Never quote, except in cases where it's mandatory by the dialect.
6440            True: Always quote.
6441
6442    Examples:
6443        >>> from sqlglot import exp, parse_one
6444        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6445        'a.b.c'
6446
6447    Returns:
6448        The table name.
6449    """
6450
6451    table = maybe_parse(table, into=Table, dialect=dialect)
6452
6453    if not table:
6454        raise ValueError(f"Cannot parse {table}")
6455
6456    return ".".join(
6457        part.sql(dialect=dialect, identify=True)
6458        if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6459        else part.name
6460        for part in table.parts
6461    )
6462
6463
6464def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6465    """Returns a case normalized table name without quotes.
6466
6467    Args:
6468        table: the table to normalize
6469        dialect: the dialect to use for normalization rules
6470        copy: whether or not to copy the expression.
6471
6472    Examples:
6473        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6474        'A-B.c'
6475    """
6476    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6477
6478    return ".".join(
6479        p.name
6480        for p in normalize_identifiers(
6481            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6482        ).parts
6483    )
6484
6485
6486def replace_tables(
6487    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6488) -> E:
6489    """Replace all tables in expression according to the mapping.
6490
6491    Args:
6492        expression: expression node to be transformed and replaced.
6493        mapping: mapping of table names.
6494        dialect: the dialect of the mapping table
6495        copy: whether or not to copy the expression.
6496
6497    Examples:
6498        >>> from sqlglot import exp, parse_one
6499        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6500        'SELECT * FROM c'
6501
6502    Returns:
6503        The mapped expression.
6504    """
6505
6506    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6507
6508    def _replace_tables(node: Expression) -> Expression:
6509        if isinstance(node, Table):
6510            new_name = mapping.get(normalize_table_name(node, dialect=dialect))
6511
6512            if new_name:
6513                return to_table(
6514                    new_name,
6515                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6516                )
6517        return node
6518
6519    return expression.transform(_replace_tables, copy=copy)
6520
6521
6522def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6523    """Replace placeholders in an expression.
6524
6525    Args:
6526        expression: expression node to be transformed and replaced.
6527        args: positional names that will substitute unnamed placeholders in the given order.
6528        kwargs: keyword arguments that will substitute named placeholders.
6529
6530    Examples:
6531        >>> from sqlglot import exp, parse_one
6532        >>> replace_placeholders(
6533        ...     parse_one("select * from :tbl where ? = ?"),
6534        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6535        ... ).sql()
6536        "SELECT * FROM foo WHERE str_col = 'b'"
6537
6538    Returns:
6539        The mapped expression.
6540    """
6541
6542    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6543        if isinstance(node, Placeholder):
6544            if node.name:
6545                new_name = kwargs.get(node.name)
6546                if new_name:
6547                    return convert(new_name)
6548            else:
6549                try:
6550                    return convert(next(args))
6551                except StopIteration:
6552                    pass
6553        return node
6554
6555    return expression.transform(_replace_placeholders, iter(args), **kwargs)
6556
6557
6558def expand(
6559    expression: Expression,
6560    sources: t.Dict[str, Subqueryable],
6561    dialect: DialectType = None,
6562    copy: bool = True,
6563) -> Expression:
6564    """Transforms an expression by expanding all referenced sources into subqueries.
6565
6566    Examples:
6567        >>> from sqlglot import parse_one
6568        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6569        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6570
6571        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6572        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6573
6574    Args:
6575        expression: The expression to expand.
6576        sources: A dictionary of name to Subqueryables.
6577        dialect: The dialect of the sources dict.
6578        copy: Whether or not to copy the expression during transformation. Defaults to True.
6579
6580    Returns:
6581        The transformed expression.
6582    """
6583    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6584
6585    def _expand(node: Expression):
6586        if isinstance(node, Table):
6587            name = normalize_table_name(node, dialect=dialect)
6588            source = sources.get(name)
6589            if source:
6590                subquery = source.subquery(node.alias or name)
6591                subquery.comments = [f"source: {name}"]
6592                return subquery.transform(_expand, copy=False)
6593        return node
6594
6595    return expression.transform(_expand, copy=copy)
6596
6597
6598def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6599    """
6600    Returns a Func expression.
6601
6602    Examples:
6603        >>> func("abs", 5).sql()
6604        'ABS(5)'
6605
6606        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6607        'CAST(5 AS DOUBLE)'
6608
6609    Args:
6610        name: the name of the function to build.
6611        args: the args used to instantiate the function of interest.
6612        dialect: the source dialect.
6613        kwargs: the kwargs used to instantiate the function of interest.
6614
6615    Note:
6616        The arguments `args` and `kwargs` are mutually exclusive.
6617
6618    Returns:
6619        An instance of the function of interest, or an anonymous function, if `name` doesn't
6620        correspond to an existing `sqlglot.expressions.Func` class.
6621    """
6622    if args and kwargs:
6623        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6624
6625    from sqlglot.dialects.dialect import Dialect
6626
6627    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6628    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6629
6630    parser = Dialect.get_or_raise(dialect)().parser()
6631    from_args_list = parser.FUNCTIONS.get(name.upper())
6632
6633    if from_args_list:
6634        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6635    else:
6636        kwargs = kwargs or {"expressions": converted}
6637        function = Anonymous(this=name, **kwargs)
6638
6639    for error_message in function.error_messages(converted):
6640        raise ValueError(error_message)
6641
6642    return function
6643
6644
6645def case(
6646    expression: t.Optional[ExpOrStr] = None,
6647    **opts,
6648) -> Case:
6649    """
6650    Initialize a CASE statement.
6651
6652    Example:
6653        case().when("a = 1", "foo").else_("bar")
6654
6655    Args:
6656        expression: Optionally, the input expression (not all dialects support this)
6657        **opts: Extra keyword arguments for parsing `expression`
6658    """
6659    if expression is not None:
6660        this = maybe_parse(expression, **opts)
6661    else:
6662        this = None
6663    return Case(this=this, ifs=[])
6664
6665
6666def true() -> Boolean:
6667    """
6668    Returns a true Boolean expression.
6669    """
6670    return Boolean(this=True)
6671
6672
6673def false() -> Boolean:
6674    """
6675    Returns a false Boolean expression.
6676    """
6677    return Boolean(this=False)
6678
6679
6680def null() -> Null:
6681    """
6682    Returns a Null expression.
6683    """
6684    return Null()
6685
6686
6687# TODO: deprecate this
6688TRUE = Boolean(this=True)
6689FALSE = Boolean(this=False)
6690NULL = 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.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT128: 'INT128'>, <Type.FLOAT: 'FLOAT'>, <Type.INT: 'INT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIME: 'TIME'>, <Type.TIMETZ: 'TIMETZ'>}
@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    pass
key = 'dpipe'
class SafeDPipe(DPipe):
3951class SafeDPipe(DPipe):
3952    pass
key = 'safedpipe'
class EQ(Binary, Predicate):
3955class EQ(Binary, Predicate):
3956    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3959class NullSafeEQ(Binary, Predicate):
3960    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3963class NullSafeNEQ(Binary, Predicate):
3964    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3968class PropertyEQ(Binary):
3969    pass
key = 'propertyeq'
class Distance(Binary):
3972class Distance(Binary):
3973    pass
key = 'distance'
class Escape(Binary):
3976class Escape(Binary):
3977    pass
key = 'escape'
class Glob(Binary, Predicate):
3980class Glob(Binary, Predicate):
3981    pass
key = 'glob'
class GT(Binary, Predicate):
3984class GT(Binary, Predicate):
3985    pass
key = 'gt'
class GTE(Binary, Predicate):
3988class GTE(Binary, Predicate):
3989    pass
key = 'gte'
class ILike(Binary, Predicate):
3992class ILike(Binary, Predicate):
3993    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3996class ILikeAny(Binary, Predicate):
3997    pass
key = 'ilikeany'
class IntDiv(Binary):
4000class IntDiv(Binary):
4001    pass
key = 'intdiv'
class Is(Binary, Predicate):
4004class Is(Binary, Predicate):
4005    pass
key = 'is'
class Kwarg(Binary):
4008class Kwarg(Binary):
4009    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4012class Like(Binary, Predicate):
4013    pass
key = 'like'
class LikeAny(Binary, Predicate):
4016class LikeAny(Binary, Predicate):
4017    pass
key = 'likeany'
class LT(Binary, Predicate):
4020class LT(Binary, Predicate):
4021    pass
key = 'lt'
class LTE(Binary, Predicate):
4024class LTE(Binary, Predicate):
4025    pass
key = 'lte'
class Mod(Binary):
4028class Mod(Binary):
4029    pass
key = 'mod'
class Mul(Binary):
4032class Mul(Binary):
4033    pass
key = 'mul'
class NEQ(Binary, Predicate):
4036class NEQ(Binary, Predicate):
4037    pass
key = 'neq'
class Operator(Binary):
4041class Operator(Binary):
4042    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4045class SimilarTo(Binary, Predicate):
4046    pass
key = 'similarto'
class Slice(Binary):
4049class Slice(Binary):
4050    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4053class Sub(Binary):
4054    pass
key = 'sub'
class ArrayOverlaps(Binary):
4057class ArrayOverlaps(Binary):
4058    pass
key = 'arrayoverlaps'
class Unary(Condition):
4063class Unary(Condition):
4064    pass
key = 'unary'
class BitwiseNot(Unary):
4067class BitwiseNot(Unary):
4068    pass
key = 'bitwisenot'
class Not(Unary):
4071class Not(Unary):
4072    pass
key = 'not'
class Paren(Unary):
4075class Paren(Unary):
4076    arg_types = {"this": True, "with": False}
4077
4078    @property
4079    def output_name(self) -> str:
4080        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):
4083class Neg(Unary):
4084    pass
key = 'neg'
class Alias(Expression):
4087class Alias(Expression):
4088    arg_types = {"this": True, "alias": False}
4089
4090    @property
4091    def output_name(self) -> str:
4092        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):
4095class Aliases(Expression):
4096    arg_types = {"this": True, "expressions": True}
4097
4098    @property
4099    def aliases(self):
4100        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
4103class AtTimeZone(Expression):
4104    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4107class Between(Predicate):
4108    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4111class Bracket(Condition):
4112    arg_types = {"this": True, "expressions": True}
4113
4114    @property
4115    def output_name(self) -> str:
4116        if len(self.expressions) == 1:
4117            return self.expressions[0].output_name
4118
4119        return super().output_name
arg_types = {'this': True, 'expressions': 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 = 'bracket'
class SafeBracket(Bracket):
4122class SafeBracket(Bracket):
4123    """Represents array lookup where OOB index yields NULL instead of causing a failure."""

Represents array lookup where OOB index yields NULL instead of causing a failure.

key = 'safebracket'
class Distinct(Expression):
4126class Distinct(Expression):
4127    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4130class In(Predicate):
4131    arg_types = {
4132        "this": True,
4133        "expressions": False,
4134        "query": False,
4135        "unnest": False,
4136        "field": False,
4137        "is_global": False,
4138    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4142class ForIn(Expression):
4143    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4146class TimeUnit(Expression):
4147    """Automatically converts unit arg into a var."""
4148
4149    arg_types = {"unit": False}
4150
4151    UNABBREVIATED_UNIT_NAME = {
4152        "d": "day",
4153        "h": "hour",
4154        "m": "minute",
4155        "ms": "millisecond",
4156        "ns": "nanosecond",
4157        "q": "quarter",
4158        "s": "second",
4159        "us": "microsecond",
4160        "w": "week",
4161        "y": "year",
4162    }
4163
4164    VAR_LIKE = (Column, Literal, Var)
4165
4166    def __init__(self, **args):
4167        unit = args.get("unit")
4168        if isinstance(unit, self.VAR_LIKE):
4169            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4170        elif isinstance(unit, Week):
4171            unit.set("this", Var(this=unit.this.name))
4172
4173        super().__init__(**args)
4174
4175    @property
4176    def unit(self) -> t.Optional[Var]:
4177        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4166    def __init__(self, **args):
4167        unit = args.get("unit")
4168        if isinstance(unit, self.VAR_LIKE):
4169            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4170        elif isinstance(unit, Week):
4171            unit.set("this", Var(this=unit.this.name))
4172
4173        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):
4180class IntervalOp(TimeUnit):
4181    arg_types = {"unit": True, "expression": True}
4182
4183    def interval(self):
4184        return Interval(
4185            this=self.expression.copy(),
4186            unit=self.unit.copy(),
4187        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4183    def interval(self):
4184        return Interval(
4185            this=self.expression.copy(),
4186            unit=self.unit.copy(),
4187        )
key = 'intervalop'
class IntervalSpan(DataType):
4193class IntervalSpan(DataType):
4194    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4197class Interval(TimeUnit):
4198    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4201class IgnoreNulls(Expression):
4202    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4205class RespectNulls(Expression):
4206    pass
key = 'respectnulls'
class Func(Condition):
4210class Func(Condition):
4211    """
4212    The base class for all function expressions.
4213
4214    Attributes:
4215        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4216            treated as a variable length argument and the argument's value will be stored as a list.
4217        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4218            for this function expression. These values are used to map this node to a name during parsing
4219            as well as to provide the function's name during SQL string generation. By default the SQL
4220            name is set to the expression's class name transformed to snake case.
4221    """
4222
4223    is_var_len_args = False
4224
4225    @classmethod
4226    def from_arg_list(cls, args):
4227        if cls.is_var_len_args:
4228            all_arg_keys = list(cls.arg_types)
4229            # If this function supports variable length argument treat the last argument as such.
4230            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4231            num_non_var = len(non_var_len_arg_keys)
4232
4233            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4234            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4235        else:
4236            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4237
4238        return cls(**args_dict)
4239
4240    @classmethod
4241    def sql_names(cls):
4242        if cls is Func:
4243            raise NotImplementedError(
4244                "SQL name is only supported by concrete function implementations"
4245            )
4246        if "_sql_names" not in cls.__dict__:
4247            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4248        return cls._sql_names
4249
4250    @classmethod
4251    def sql_name(cls):
4252        return cls.sql_names()[0]
4253
4254    @classmethod
4255    def default_parser_mappings(cls):
4256        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):
4225    @classmethod
4226    def from_arg_list(cls, args):
4227        if cls.is_var_len_args:
4228            all_arg_keys = list(cls.arg_types)
4229            # If this function supports variable length argument treat the last argument as such.
4230            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4231            num_non_var = len(non_var_len_arg_keys)
4232
4233            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4234            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4235        else:
4236            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4237
4238        return cls(**args_dict)
@classmethod
def sql_names(cls):
4240    @classmethod
4241    def sql_names(cls):
4242        if cls is Func:
4243            raise NotImplementedError(
4244                "SQL name is only supported by concrete function implementations"
4245            )
4246        if "_sql_names" not in cls.__dict__:
4247            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4248        return cls._sql_names
@classmethod
def sql_name(cls):
4250    @classmethod
4251    def sql_name(cls):
4252        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4254    @classmethod
4255    def default_parser_mappings(cls):
4256        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4259class AggFunc(Func):
4260    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4263class ParameterizedAgg(AggFunc):
4264    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4267class Abs(Func):
4268    pass
key = 'abs'
class ArgMax(AggFunc):
4271class ArgMax(AggFunc):
4272    arg_types = {"this": True, "expression": True, "count": False}
4273    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4276class ArgMin(AggFunc):
4277    arg_types = {"this": True, "expression": True, "count": False}
4278    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4281class ApproxTopK(AggFunc):
4282    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4285class Flatten(Func):
4286    pass
key = 'flatten'
class Transform(Func):
4290class Transform(Func):
4291    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4294class Anonymous(Func):
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 = 'anonymous'
class Hll(AggFunc):
4301class Hll(AggFunc):
4302    arg_types = {"this": True, "expressions": False}
4303    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4306class ApproxDistinct(AggFunc):
4307    arg_types = {"this": True, "accuracy": False}
4308    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4311class Array(Func):
4312    arg_types = {"expressions": False}
4313    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4318class ToChar(Func):
4319    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4322class GenerateSeries(Func):
4323    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4326class ArrayAgg(AggFunc):
4327    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4330class ArrayUniqueAgg(AggFunc):
4331    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4334class ArrayAll(Func):
4335    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4338class ArrayAny(Func):
4339    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4342class ArrayConcat(Func):
4343    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4344    arg_types = {"this": True, "expressions": False}
4345    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4348class ArrayContains(Binary, Func):
4349    pass
key = 'arraycontains'
class ArrayContained(Binary):
4352class ArrayContained(Binary):
4353    pass
key = 'arraycontained'
class ArrayFilter(Func):
4356class ArrayFilter(Func):
4357    arg_types = {"this": True, "expression": True}
4358    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4361class ArrayJoin(Func):
4362    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4365class ArraySize(Func):
4366    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4369class ArraySort(Func):
4370    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4373class ArraySum(Func):
4374    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4377class ArrayUnionAgg(AggFunc):
4378    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4381class Avg(AggFunc):
4382    pass
key = 'avg'
class AnyValue(AggFunc):
4385class AnyValue(AggFunc):
4386    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):
4389class First(Func):
4390    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4393class Last(Func):
4394    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4397class Case(Func):
4398    arg_types = {"this": False, "ifs": True, "default": False}
4399
4400    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4401        instance = maybe_copy(self, copy)
4402        instance.append(
4403            "ifs",
4404            If(
4405                this=maybe_parse(condition, copy=copy, **opts),
4406                true=maybe_parse(then, copy=copy, **opts),
4407            ),
4408        )
4409        return instance
4410
4411    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4412        instance = maybe_copy(self, copy)
4413        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4414        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:
4400    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4401        instance = maybe_copy(self, copy)
4402        instance.append(
4403            "ifs",
4404            If(
4405                this=maybe_parse(condition, copy=copy, **opts),
4406                true=maybe_parse(then, copy=copy, **opts),
4407            ),
4408        )
4409        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4411    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4412        instance = maybe_copy(self, copy)
4413        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4414        return instance
key = 'case'
class Cast(Func):
4417class Cast(Func):
4418    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4419
4420    @property
4421    def name(self) -> str:
4422        return self.this.name
4423
4424    @property
4425    def to(self) -> DataType:
4426        return self.args["to"]
4427
4428    @property
4429    def output_name(self) -> str:
4430        return self.name
4431
4432    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4433        """
4434        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4435        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4436        array<int> != array<float>.
4437
4438        Args:
4439            dtypes: the data types to compare this Cast's DataType to.
4440
4441        Returns:
4442            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4443        """
4444        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:
4432    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4433        """
4434        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4435        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4436        array<int> != array<float>.
4437
4438        Args:
4439            dtypes: the data types to compare this Cast's DataType to.
4440
4441        Returns:
4442            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4443        """
4444        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):
4447class TryCast(Cast):
4448    pass
key = 'trycast'
class CastToStrType(Func):
4451class CastToStrType(Func):
4452    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4455class Collate(Binary, Func):
4456    pass
key = 'collate'
class Ceil(Func):
4459class Ceil(Func):
4460    arg_types = {"this": True, "decimals": False}
4461    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4464class Coalesce(Func):
4465    arg_types = {"this": True, "expressions": False}
4466    is_var_len_args = True
4467    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4470class Chr(Func):
4471    arg_types = {"this": True, "charset": False, "expressions": False}
4472    is_var_len_args = True
4473    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4476class Concat(Func):
4477    arg_types = {"expressions": True}
4478    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4481class SafeConcat(Concat):
4482    pass
key = 'safeconcat'
class ConcatWs(Concat):
4485class ConcatWs(Concat):
4486    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4489class Count(AggFunc):
4490    arg_types = {"this": False, "expressions": False}
4491    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4494class CountIf(AggFunc):
4495    pass
key = 'countif'
class CurrentDate(Func):
4498class CurrentDate(Func):
4499    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4502class CurrentDatetime(Func):
4503    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4506class CurrentTime(Func):
4507    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4510class CurrentTimestamp(Func):
4511    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4514class CurrentUser(Func):
4515    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4518class DateAdd(Func, IntervalOp):
4519    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4522class DateSub(Func, IntervalOp):
4523    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4526class DateDiff(Func, TimeUnit):
4527    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4528    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4531class DateTrunc(Func):
4532    arg_types = {"unit": True, "this": True, "zone": False}
4533
4534    @property
4535    def unit(self) -> Expression:
4536        return self.args["unit"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4539class DatetimeAdd(Func, IntervalOp):
4540    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4543class DatetimeSub(Func, IntervalOp):
4544    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4547class DatetimeDiff(Func, TimeUnit):
4548    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4551class DatetimeTrunc(Func, TimeUnit):
4552    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4555class DayOfWeek(Func):
4556    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4559class DayOfMonth(Func):
4560    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4563class DayOfYear(Func):
4564    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4567class ToDays(Func):
4568    pass
key = 'todays'
class WeekOfYear(Func):
4571class WeekOfYear(Func):
4572    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4575class MonthsBetween(Func):
4576    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4579class LastDateOfMonth(Func):
4580    pass
key = 'lastdateofmonth'
class Extract(Func):
4583class Extract(Func):
4584    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4587class Timestamp(Func):
4588    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4591class TimestampAdd(Func, TimeUnit):
4592    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4595class TimestampSub(Func, TimeUnit):
4596    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4599class TimestampDiff(Func, TimeUnit):
4600    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4603class TimestampTrunc(Func, TimeUnit):
4604    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4607class TimeAdd(Func, TimeUnit):
4608    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4611class TimeSub(Func, TimeUnit):
4612    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4615class TimeDiff(Func, TimeUnit):
4616    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4619class TimeTrunc(Func, TimeUnit):
4620    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4623class DateFromParts(Func):
4624    _sql_names = ["DATEFROMPARTS"]
4625    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4628class DateStrToDate(Func):
4629    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4632class DateToDateStr(Func):
4633    pass
key = 'datetodatestr'
class DateToDi(Func):
4636class DateToDi(Func):
4637    pass
key = 'datetodi'
class Date(Func):
4641class Date(Func):
4642    arg_types = {"this": False, "zone": False, "expressions": False}
4643    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4646class Day(Func):
4647    pass
key = 'day'
class Decode(Func):
4650class Decode(Func):
4651    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4654class DiToDate(Func):
4655    pass
key = 'ditodate'
class Encode(Func):
4658class Encode(Func):
4659    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4662class Exp(Func):
4663    pass
key = 'exp'
class Explode(Func):
4667class Explode(Func):
4668    arg_types = {"this": True, "expressions": False}
4669    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4672class ExplodeOuter(Explode):
4673    pass
key = 'explodeouter'
class Posexplode(Explode):
4676class Posexplode(Explode):
4677    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4680class PosexplodeOuter(Posexplode):
4681    pass
key = 'posexplodeouter'
class Floor(Func):
4684class Floor(Func):
4685    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4688class FromBase64(Func):
4689    pass
key = 'frombase64'
class ToBase64(Func):
4692class ToBase64(Func):
4693    pass
key = 'tobase64'
class Greatest(Func):
4696class Greatest(Func):
4697    arg_types = {"this": True, "expressions": False}
4698    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4701class GroupConcat(AggFunc):
4702    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4705class Hex(Func):
4706    pass
key = 'hex'
class Xor(Connector, Func):
4709class Xor(Connector, Func):
4710    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4713class If(Func):
4714    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4717class Nullif(Func):
4718    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4721class Initcap(Func):
4722    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4725class IsNan(Func):
4726    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4729class IsInf(Func):
4730    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4733class FormatJson(Expression):
4734    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4737class JSONKeyValue(Expression):
4738    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4741class JSONObject(Func):
4742    arg_types = {
4743        "expressions": False,
4744        "null_handling": False,
4745        "unique_keys": False,
4746        "return_type": False,
4747        "encoding": False,
4748    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4752class JSONArray(Func):
4753    arg_types = {
4754        "expressions": True,
4755        "null_handling": False,
4756        "return_type": False,
4757        "strict": False,
4758    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4762class JSONArrayAgg(Func):
4763    arg_types = {
4764        "this": True,
4765        "order": False,
4766        "null_handling": False,
4767        "return_type": False,
4768        "strict": False,
4769    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4774class JSONColumnDef(Expression):
4775    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):
4778class JSONSchema(Expression):
4779    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4783class JSONTable(Func):
4784    arg_types = {
4785        "this": True,
4786        "schema": True,
4787        "path": False,
4788        "error_handling": False,
4789        "empty_handling": False,
4790    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4793class OpenJSONColumnDef(Expression):
4794    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):
4797class OpenJSON(Func):
4798    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4801class JSONBContains(Binary):
4802    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4805class JSONExtract(Binary, Func):
4806    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4809class JSONExtractScalar(JSONExtract):
4810    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4813class JSONBExtract(JSONExtract):
4814    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4817class JSONBExtractScalar(JSONExtract):
4818    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4821class JSONFormat(Func):
4822    arg_types = {"this": False, "options": False}
4823    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4827class JSONArrayContains(Binary, Predicate, Func):
4828    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4831class ParseJSON(Func):
4832    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4833    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4834    arg_types = {"this": True, "expressions": False}
4835    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
4838class Least(Func):
4839    arg_types = {"this": True, "expressions": False}
4840    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4843class Left(Func):
4844    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4851class Length(Func):
4852    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4855class Levenshtein(Func):
4856    arg_types = {
4857        "this": True,
4858        "expression": False,
4859        "ins_cost": False,
4860        "del_cost": False,
4861        "sub_cost": False,
4862    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4865class Ln(Func):
4866    pass
key = 'ln'
class Log(Func):
4869class Log(Func):
4870    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4873class Log2(Func):
4874    pass
key = 'log2'
class Log10(Func):
4877class Log10(Func):
4878    pass
key = 'log10'
class LogicalOr(AggFunc):
4881class LogicalOr(AggFunc):
4882    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4885class LogicalAnd(AggFunc):
4886    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4889class Lower(Func):
4890    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4893class Map(Func):
4894    arg_types = {"keys": False, "values": False}
4895
4896    @property
4897    def keys(self) -> t.List[Expression]:
4898        keys = self.args.get("keys")
4899        return keys.expressions if keys else []
4900
4901    @property
4902    def values(self) -> t.List[Expression]:
4903        values = self.args.get("values")
4904        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
values: List[Expression]
key = 'map'
class MapFromEntries(Func):
4907class MapFromEntries(Func):
4908    pass
key = 'mapfromentries'
class StarMap(Func):
4911class StarMap(Func):
4912    pass
key = 'starmap'
class VarMap(Func):
4915class VarMap(Func):
4916    arg_types = {"keys": True, "values": True}
4917    is_var_len_args = True
4918
4919    @property
4920    def keys(self) -> t.List[Expression]:
4921        return self.args["keys"].expressions
4922
4923    @property
4924    def values(self) -> t.List[Expression]:
4925        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):
4929class MatchAgainst(Func):
4930    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4933class Max(AggFunc):
4934    arg_types = {"this": True, "expressions": False}
4935    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4938class MD5(Func):
4939    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4943class MD5Digest(Func):
4944    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4947class Min(AggFunc):
4948    arg_types = {"this": True, "expressions": False}
4949    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4952class Month(Func):
4953    pass
key = 'month'
class Nvl2(Func):
4956class Nvl2(Func):
4957    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
4961class Predict(Func):
4962    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
4965class Pow(Binary, Func):
4966    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4969class PercentileCont(AggFunc):
4970    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4973class PercentileDisc(AggFunc):
4974    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4977class Quantile(AggFunc):
4978    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4981class ApproxQuantile(Quantile):
4982    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):
4985class RangeN(Func):
4986    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4989class ReadCSV(Func):
4990    _sql_names = ["READ_CSV"]
4991    is_var_len_args = True
4992    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4995class Reduce(Func):
4996    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):
4999class RegexpExtract(Func):
5000    arg_types = {
5001        "this": True,
5002        "expression": True,
5003        "position": False,
5004        "occurrence": False,
5005        "parameters": False,
5006        "group": False,
5007    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5010class RegexpReplace(Func):
5011    arg_types = {
5012        "this": True,
5013        "expression": True,
5014        "replacement": True,
5015        "position": False,
5016        "occurrence": False,
5017        "parameters": False,
5018        "modifiers": False,
5019    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5022class RegexpLike(Binary, Func):
5023    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5026class RegexpILike(Binary, Func):
5027    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5032class RegexpSplit(Func):
5033    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5036class Repeat(Func):
5037    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5040class Round(Func):
5041    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5044class RowNumber(Func):
5045    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5048class SafeDivide(Func):
5049    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5052class SHA(Func):
5053    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5056class SHA2(Func):
5057    _sql_names = ["SHA2"]
5058    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5061class SortArray(Func):
5062    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5065class Split(Func):
5066    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5071class Substring(Func):
5072    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5075class StandardHash(Func):
5076    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5079class StartsWith(Func):
5080    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5081    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5084class StrPosition(Func):
5085    arg_types = {
5086        "this": True,
5087        "substr": True,
5088        "position": False,
5089        "instance": False,
5090    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5093class StrToDate(Func):
5094    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5097class StrToTime(Func):
5098    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5103class StrToUnix(Func):
5104    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5109class StrToMap(Func):
5110    arg_types = {
5111        "this": True,
5112        "pair_delim": False,
5113        "key_value_delim": False,
5114        "duplicate_resolution_callback": False,
5115    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5118class NumberToStr(Func):
5119    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5122class FromBase(Func):
5123    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5126class Struct(Func):
5127    arg_types = {"expressions": False}
5128    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5131class StructExtract(Func):
5132    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5137class Stuff(Func):
5138    _sql_names = ["STUFF", "INSERT"]
5139    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):
5142class Sum(AggFunc):
5143    pass
key = 'sum'
class Sqrt(Func):
5146class Sqrt(Func):
5147    pass
key = 'sqrt'
class Stddev(AggFunc):
5150class Stddev(AggFunc):
5151    pass
key = 'stddev'
class StddevPop(AggFunc):
5154class StddevPop(AggFunc):
5155    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5158class StddevSamp(AggFunc):
5159    pass
key = 'stddevsamp'
class TimeToStr(Func):
5162class TimeToStr(Func):
5163    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5166class TimeToTimeStr(Func):
5167    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5170class TimeToUnix(Func):
5171    pass
key = 'timetounix'
class TimeStrToDate(Func):
5174class TimeStrToDate(Func):
5175    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5178class TimeStrToTime(Func):
5179    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5182class TimeStrToUnix(Func):
5183    pass
key = 'timestrtounix'
class Trim(Func):
5186class Trim(Func):
5187    arg_types = {
5188        "this": True,
5189        "expression": False,
5190        "position": False,
5191        "collation": False,
5192    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5195class TsOrDsAdd(Func, TimeUnit):
5196    # return_type is used to correctly cast the arguments of this expression when transpiling it
5197    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5198
5199    @property
5200    def return_type(self) -> DataType:
5201        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):
5204class TsOrDsDiff(Func, TimeUnit):
5205    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5208class TsOrDsToDateStr(Func):
5209    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5212class TsOrDsToDate(Func):
5213    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
5216class TsOrDiToDi(Func):
5217    pass
key = 'tsorditodi'
class Unhex(Func):
5220class Unhex(Func):
5221    pass
key = 'unhex'
class UnixToStr(Func):
5224class UnixToStr(Func):
5225    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5230class UnixToTime(Func):
5231    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5232
5233    SECONDS = Literal.string("seconds")
5234    MILLIS = Literal.string("millis")
5235    MICROS = Literal.string("micros")
5236    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):
5239class UnixToTimeStr(Func):
5240    pass
key = 'unixtotimestr'
class Upper(Func):
5243class Upper(Func):
5244    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5247class Variance(AggFunc):
5248    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5251class VariancePop(AggFunc):
5252    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5255class Week(Func):
5256    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5259class XMLTable(Func):
5260    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):
5263class Year(Func):
5264    pass
key = 'year'
class Use(Expression):
5267class Use(Expression):
5268    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5271class Merge(Expression):
5272    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):
5275class When(Func):
5276    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):
5281class NextValueFor(Func):
5282    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 'SafeConcat'>, <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:
5319def maybe_parse(
5320    sql_or_expression: ExpOrStr,
5321    *,
5322    into: t.Optional[IntoType] = None,
5323    dialect: DialectType = None,
5324    prefix: t.Optional[str] = None,
5325    copy: bool = False,
5326    **opts,
5327) -> Expression:
5328    """Gracefully handle a possible string or expression.
5329
5330    Example:
5331        >>> maybe_parse("1")
5332        (LITERAL this: 1, is_string: False)
5333        >>> maybe_parse(to_identifier("x"))
5334        (IDENTIFIER this: x, quoted: False)
5335
5336    Args:
5337        sql_or_expression: the SQL code string or an expression
5338        into: the SQLGlot Expression to parse into
5339        dialect: the dialect used to parse the input expressions (in the case that an
5340            input expression is a SQL string).
5341        prefix: a string to prefix the sql with before it gets parsed
5342            (automatically includes a space)
5343        copy: whether or not to copy the expression.
5344        **opts: other options to use to parse the input expressions (again, in the case
5345            that an input expression is a SQL string).
5346
5347    Returns:
5348        Expression: the parsed or given expression.
5349    """
5350    if isinstance(sql_or_expression, Expression):
5351        if copy:
5352            return sql_or_expression.copy()
5353        return sql_or_expression
5354
5355    if sql_or_expression is None:
5356        raise ParseError(f"SQL cannot be None")
5357
5358    import sqlglot
5359
5360    sql = str(sql_or_expression)
5361    if prefix:
5362        sql = f"{prefix} {sql}"
5363
5364    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):
5377def maybe_copy(instance, copy=True):
5378    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:
5559def union(
5560    left: ExpOrStr,
5561    right: ExpOrStr,
5562    distinct: bool = True,
5563    dialect: DialectType = None,
5564    copy: bool = True,
5565    **opts,
5566) -> Union:
5567    """
5568    Initializes a syntax tree from one UNION expression.
5569
5570    Example:
5571        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5572        'SELECT * FROM foo UNION SELECT * FROM bla'
5573
5574    Args:
5575        left: the SQL code string corresponding to the left-hand side.
5576            If an `Expression` instance is passed, it will be used as-is.
5577        right: the SQL code string corresponding to the right-hand side.
5578            If an `Expression` instance is passed, it will be used as-is.
5579        distinct: set the DISTINCT flag if and only if this is true.
5580        dialect: the dialect used to parse the input expression.
5581        copy: whether or not to copy the expression.
5582        opts: other options to use to parse the input expressions.
5583
5584    Returns:
5585        The new Union instance.
5586    """
5587    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5588    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5589
5590    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:
5593def intersect(
5594    left: ExpOrStr,
5595    right: ExpOrStr,
5596    distinct: bool = True,
5597    dialect: DialectType = None,
5598    copy: bool = True,
5599    **opts,
5600) -> Intersect:
5601    """
5602    Initializes a syntax tree from one INTERSECT expression.
5603
5604    Example:
5605        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5606        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5607
5608    Args:
5609        left: the SQL code string corresponding to the left-hand side.
5610            If an `Expression` instance is passed, it will be used as-is.
5611        right: the SQL code string corresponding to the right-hand side.
5612            If an `Expression` instance is passed, it will be used as-is.
5613        distinct: set the DISTINCT flag if and only if this is true.
5614        dialect: the dialect used to parse the input expression.
5615        copy: whether or not to copy the expression.
5616        opts: other options to use to parse the input expressions.
5617
5618    Returns:
5619        The new Intersect instance.
5620    """
5621    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5622    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5623
5624    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:
5627def except_(
5628    left: ExpOrStr,
5629    right: ExpOrStr,
5630    distinct: bool = True,
5631    dialect: DialectType = None,
5632    copy: bool = True,
5633    **opts,
5634) -> Except:
5635    """
5636    Initializes a syntax tree from one EXCEPT expression.
5637
5638    Example:
5639        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5640        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5641
5642    Args:
5643        left: the SQL code string corresponding to the left-hand side.
5644            If an `Expression` instance is passed, it will be used as-is.
5645        right: the SQL code string corresponding to the right-hand side.
5646            If an `Expression` instance is passed, it will be used as-is.
5647        distinct: set the DISTINCT flag if and only if this is true.
5648        dialect: the dialect used to parse the input expression.
5649        copy: whether or not to copy the expression.
5650        opts: other options to use to parse the input expressions.
5651
5652    Returns:
5653        The new Except instance.
5654    """
5655    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5656    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5657
5658    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:
5661def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5662    """
5663    Initializes a syntax tree from one or multiple SELECT expressions.
5664
5665    Example:
5666        >>> select("col1", "col2").from_("tbl").sql()
5667        'SELECT col1, col2 FROM tbl'
5668
5669    Args:
5670        *expressions: the SQL code string to parse as the expressions of a
5671            SELECT statement. If an Expression instance is passed, this is used as-is.
5672        dialect: the dialect used to parse the input expressions (in the case that an
5673            input expression is a SQL string).
5674        **opts: other options to use to parse the input expressions (again, in the case
5675            that an input expression is a SQL string).
5676
5677    Returns:
5678        Select: the syntax tree for the SELECT statement.
5679    """
5680    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:
5683def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5684    """
5685    Initializes a syntax tree from a FROM expression.
5686
5687    Example:
5688        >>> from_("tbl").select("col1", "col2").sql()
5689        'SELECT col1, col2 FROM tbl'
5690
5691    Args:
5692        *expression: the SQL code string to parse as the FROM expressions of a
5693            SELECT statement. If an Expression instance is passed, this is used as-is.
5694        dialect: the dialect used to parse the input expression (in the case that the
5695            input expression is a SQL string).
5696        **opts: other options to use to parse the input expressions (again, in the case
5697            that the input expression is a SQL string).
5698
5699    Returns:
5700        Select: the syntax tree for the SELECT statement.
5701    """
5702    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:
5705def update(
5706    table: str | Table,
5707    properties: dict,
5708    where: t.Optional[ExpOrStr] = None,
5709    from_: t.Optional[ExpOrStr] = None,
5710    dialect: DialectType = None,
5711    **opts,
5712) -> Update:
5713    """
5714    Creates an update statement.
5715
5716    Example:
5717        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5718        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5719
5720    Args:
5721        *properties: dictionary of properties to set which are
5722            auto converted to sql objects eg None -> NULL
5723        where: sql conditional parsed into a WHERE statement
5724        from_: sql statement parsed into a FROM statement
5725        dialect: the dialect used to parse the input expressions.
5726        **opts: other options to use to parse the input expressions.
5727
5728    Returns:
5729        Update: the syntax tree for the UPDATE statement.
5730    """
5731    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5732    update_expr.set(
5733        "expressions",
5734        [
5735            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5736            for k, v in properties.items()
5737        ],
5738    )
5739    if from_:
5740        update_expr.set(
5741            "from",
5742            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5743        )
5744    if isinstance(where, Condition):
5745        where = Where(this=where)
5746    if where:
5747        update_expr.set(
5748            "where",
5749            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5750        )
5751    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:
5754def delete(
5755    table: ExpOrStr,
5756    where: t.Optional[ExpOrStr] = None,
5757    returning: t.Optional[ExpOrStr] = None,
5758    dialect: DialectType = None,
5759    **opts,
5760) -> Delete:
5761    """
5762    Builds a delete statement.
5763
5764    Example:
5765        >>> delete("my_table", where="id > 1").sql()
5766        'DELETE FROM my_table WHERE id > 1'
5767
5768    Args:
5769        where: sql conditional parsed into a WHERE statement
5770        returning: sql conditional parsed into a RETURNING statement
5771        dialect: the dialect used to parse the input expressions.
5772        **opts: other options to use to parse the input expressions.
5773
5774    Returns:
5775        Delete: the syntax tree for the DELETE statement.
5776    """
5777    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5778    if where:
5779        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5780    if returning:
5781        delete_expr = t.cast(
5782            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5783        )
5784    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:
5787def insert(
5788    expression: ExpOrStr,
5789    into: ExpOrStr,
5790    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5791    overwrite: t.Optional[bool] = None,
5792    returning: t.Optional[ExpOrStr] = None,
5793    dialect: DialectType = None,
5794    copy: bool = True,
5795    **opts,
5796) -> Insert:
5797    """
5798    Builds an INSERT statement.
5799
5800    Example:
5801        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5802        'INSERT INTO tbl VALUES (1, 2, 3)'
5803
5804    Args:
5805        expression: the sql string or expression of the INSERT statement
5806        into: the tbl to insert data to.
5807        columns: optionally the table's column names.
5808        overwrite: whether to INSERT OVERWRITE or not.
5809        returning: sql conditional parsed into a RETURNING statement
5810        dialect: the dialect used to parse the input expressions.
5811        copy: whether or not to copy the expression.
5812        **opts: other options to use to parse the input expressions.
5813
5814    Returns:
5815        Insert: the syntax tree for the INSERT statement.
5816    """
5817    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5818    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5819
5820    if columns:
5821        this = _apply_list_builder(
5822            *columns,
5823            instance=Schema(this=this),
5824            arg="expressions",
5825            into=Identifier,
5826            copy=False,
5827            dialect=dialect,
5828            **opts,
5829        )
5830
5831    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5832
5833    if returning:
5834        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5835
5836    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:
5839def condition(
5840    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5841) -> Condition:
5842    """
5843    Initialize a logical condition expression.
5844
5845    Example:
5846        >>> condition("x=1").sql()
5847        'x = 1'
5848
5849        This is helpful for composing larger logical syntax trees:
5850        >>> where = condition("x=1")
5851        >>> where = where.and_("y=1")
5852        >>> Select().from_("tbl").select("*").where(where).sql()
5853        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5854
5855    Args:
5856        *expression: the SQL code string to parse.
5857            If an Expression instance is passed, this is used as-is.
5858        dialect: the dialect used to parse the input expression (in the case that the
5859            input expression is a SQL string).
5860        copy: Whether or not to copy `expression` (only applies to expressions).
5861        **opts: other options to use to parse the input expressions (again, in the case
5862            that the input expression is a SQL string).
5863
5864    Returns:
5865        The new Condition instance
5866    """
5867    return maybe_parse(
5868        expression,
5869        into=Condition,
5870        dialect=dialect,
5871        copy=copy,
5872        **opts,
5873    )

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:
5876def and_(
5877    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5878) -> Condition:
5879    """
5880    Combine multiple conditions with an AND logical operator.
5881
5882    Example:
5883        >>> and_("x=1", and_("y=1", "z=1")).sql()
5884        'x = 1 AND (y = 1 AND z = 1)'
5885
5886    Args:
5887        *expressions: the SQL code strings to parse.
5888            If an Expression instance is passed, this is used as-is.
5889        dialect: the dialect used to parse the input expression.
5890        copy: whether or not to copy `expressions` (only applies to Expressions).
5891        **opts: other options to use to parse the input expressions.
5892
5893    Returns:
5894        And: the new condition
5895    """
5896    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:
5899def or_(
5900    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5901) -> Condition:
5902    """
5903    Combine multiple conditions with an OR logical operator.
5904
5905    Example:
5906        >>> or_("x=1", or_("y=1", "z=1")).sql()
5907        'x = 1 OR (y = 1 OR z = 1)'
5908
5909    Args:
5910        *expressions: the SQL code strings to parse.
5911            If an Expression instance is passed, this is used as-is.
5912        dialect: the dialect used to parse the input expression.
5913        copy: whether or not to copy `expressions` (only applies to Expressions).
5914        **opts: other options to use to parse the input expressions.
5915
5916    Returns:
5917        Or: the new condition
5918    """
5919    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:
5922def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5923    """
5924    Wrap a condition with a NOT operator.
5925
5926    Example:
5927        >>> not_("this_suit='black'").sql()
5928        "NOT this_suit = 'black'"
5929
5930    Args:
5931        expression: the SQL code string to parse.
5932            If an Expression instance is passed, this is used as-is.
5933        dialect: the dialect used to parse the input expression.
5934        copy: whether to copy the expression or not.
5935        **opts: other options to use to parse the input expressions.
5936
5937    Returns:
5938        The new condition.
5939    """
5940    this = condition(
5941        expression,
5942        dialect=dialect,
5943        copy=copy,
5944        **opts,
5945    )
5946    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:
5949def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5950    """
5951    Wrap an expression in parentheses.
5952
5953    Example:
5954        >>> paren("5 + 3").sql()
5955        '(5 + 3)'
5956
5957    Args:
5958        expression: the SQL code string to parse.
5959            If an Expression instance is passed, this is used as-is.
5960        copy: whether to copy the expression or not.
5961
5962    Returns:
5963        The wrapped expression.
5964    """
5965    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):
5983def to_identifier(name, quoted=None, copy=True):
5984    """Builds an identifier.
5985
5986    Args:
5987        name: The name to turn into an identifier.
5988        quoted: Whether or not force quote the identifier.
5989        copy: Whether or not to copy name if it's an Identifier.
5990
5991    Returns:
5992        The identifier ast node.
5993    """
5994
5995    if name is None:
5996        return None
5997
5998    if isinstance(name, Identifier):
5999        identifier = maybe_copy(name, copy)
6000    elif isinstance(name, str):
6001        identifier = Identifier(
6002            this=name,
6003            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6004        )
6005    else:
6006        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6007    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:
6010def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6011    """
6012    Parses a given string into an identifier.
6013
6014    Args:
6015        name: The name to parse into an identifier.
6016        dialect: The dialect to parse against.
6017
6018    Returns:
6019        The identifier ast node.
6020    """
6021    try:
6022        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6023    except ParseError:
6024        expression = to_identifier(name)
6025
6026    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:
6032def to_interval(interval: str | Literal) -> Interval:
6033    """Builds an interval expression from a string like '1 day' or '5 months'."""
6034    if isinstance(interval, Literal):
6035        if not interval.is_string:
6036            raise ValueError("Invalid interval string.")
6037
6038        interval = interval.this
6039
6040    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6041
6042    if not interval_parts:
6043        raise ValueError("Invalid interval string.")
6044
6045    return Interval(
6046        this=Literal.string(interval_parts.group(1)),
6047        unit=Var(this=interval_parts.group(2)),
6048    )

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]:
6061def to_table(
6062    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6063) -> t.Optional[Table]:
6064    """
6065    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6066    If a table is passed in then that table is returned.
6067
6068    Args:
6069        sql_path: a `[catalog].[schema].[table]` string.
6070        dialect: the source dialect according to which the table name will be parsed.
6071        copy: Whether or not to copy a table if it is passed in.
6072        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6073
6074    Returns:
6075        A table expression.
6076    """
6077    if sql_path is None or isinstance(sql_path, Table):
6078        return maybe_copy(sql_path, copy=copy)
6079    if not isinstance(sql_path, str):
6080        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6081
6082    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6083    if table:
6084        for k, v in kwargs.items():
6085            table.set(k, v)
6086
6087    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:
6090def to_column(sql_path: str | Column, **kwargs) -> Column:
6091    """
6092    Create a column from a `[table].[column]` sql path. Schema is optional.
6093
6094    If a column is passed in then that column is returned.
6095
6096    Args:
6097        sql_path: `[table].[column]` string
6098    Returns:
6099        Table: A column expression
6100    """
6101    if sql_path is None or isinstance(sql_path, Column):
6102        return sql_path
6103    if not isinstance(sql_path, str):
6104        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6105    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):
6108def alias_(
6109    expression: ExpOrStr,
6110    alias: str | Identifier,
6111    table: bool | t.Sequence[str | Identifier] = False,
6112    quoted: t.Optional[bool] = None,
6113    dialect: DialectType = None,
6114    copy: bool = True,
6115    **opts,
6116):
6117    """Create an Alias expression.
6118
6119    Example:
6120        >>> alias_('foo', 'bar').sql()
6121        'foo AS bar'
6122
6123        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6124        '(SELECT 1, 2) AS bar(a, b)'
6125
6126    Args:
6127        expression: the SQL code strings to parse.
6128            If an Expression instance is passed, this is used as-is.
6129        alias: the alias name to use. If the name has
6130            special characters it is quoted.
6131        table: Whether or not to create a table alias, can also be a list of columns.
6132        quoted: whether or not to quote the alias
6133        dialect: the dialect used to parse the input expression.
6134        copy: Whether or not to copy the expression.
6135        **opts: other options to use to parse the input expressions.
6136
6137    Returns:
6138        Alias: the aliased expression
6139    """
6140    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6141    alias = to_identifier(alias, quoted=quoted)
6142
6143    if table:
6144        table_alias = TableAlias(this=alias)
6145        exp.set("alias", table_alias)
6146
6147        if not isinstance(table, bool):
6148            for column in table:
6149                table_alias.append("columns", to_identifier(column, quoted=quoted))
6150
6151        return exp
6152
6153    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6154    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6155    # for the complete Window expression.
6156    #
6157    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6158
6159    if "alias" in exp.arg_types and not isinstance(exp, Window):
6160        exp.set("alias", alias)
6161        return exp
6162    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:
6165def subquery(
6166    expression: ExpOrStr,
6167    alias: t.Optional[Identifier | str] = None,
6168    dialect: DialectType = None,
6169    **opts,
6170) -> Select:
6171    """
6172    Build a subquery expression.
6173
6174    Example:
6175        >>> subquery('select x from tbl', 'bar').select('x').sql()
6176        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6177
6178    Args:
6179        expression: the SQL code strings to parse.
6180            If an Expression instance is passed, this is used as-is.
6181        alias: the alias name to use.
6182        dialect: the dialect used to parse the input expression.
6183        **opts: other options to use to parse the input expressions.
6184
6185    Returns:
6186        A new Select instance with the subquery expression included.
6187    """
6188
6189    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6190    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:
6193def column(
6194    col: str | Identifier,
6195    table: t.Optional[str | Identifier] = None,
6196    db: t.Optional[str | Identifier] = None,
6197    catalog: t.Optional[str | Identifier] = None,
6198    quoted: t.Optional[bool] = None,
6199) -> Column:
6200    """
6201    Build a Column.
6202
6203    Args:
6204        col: Column name.
6205        table: Table name.
6206        db: Database name.
6207        catalog: Catalog name.
6208        quoted: Whether to force quotes on the column's identifiers.
6209
6210    Returns:
6211        The new Column instance.
6212    """
6213    return Column(
6214        this=to_identifier(col, quoted=quoted),
6215        table=to_identifier(table, quoted=quoted),
6216        db=to_identifier(db, quoted=quoted),
6217        catalog=to_identifier(catalog, quoted=quoted),
6218    )

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:
6221def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6222    """Cast an expression to a data type.
6223
6224    Example:
6225        >>> cast('x + 1', 'int').sql()
6226        'CAST(x + 1 AS INT)'
6227
6228    Args:
6229        expression: The expression to cast.
6230        to: The datatype to cast to.
6231
6232    Returns:
6233        The new Cast instance.
6234    """
6235    expression = maybe_parse(expression, **opts)
6236    data_type = DataType.build(to, **opts)
6237    expression = Cast(this=expression, to=data_type)
6238    expression.type = data_type
6239    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:
6242def table_(
6243    table: Identifier | str,
6244    db: t.Optional[Identifier | str] = None,
6245    catalog: t.Optional[Identifier | str] = None,
6246    quoted: t.Optional[bool] = None,
6247    alias: t.Optional[Identifier | str] = None,
6248) -> Table:
6249    """Build a Table.
6250
6251    Args:
6252        table: Table name.
6253        db: Database name.
6254        catalog: Catalog name.
6255        quote: Whether to force quotes on the table's identifiers.
6256        alias: Table's alias.
6257
6258    Returns:
6259        The new Table instance.
6260    """
6261    return Table(
6262        this=to_identifier(table, quoted=quoted) if table else None,
6263        db=to_identifier(db, quoted=quoted) if db else None,
6264        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6265        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6266    )

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

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

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:
6346def convert(value: t.Any, copy: bool = False) -> Expression:
6347    """Convert a python value into an expression object.
6348
6349    Raises an error if a conversion is not possible.
6350
6351    Args:
6352        value: A python object.
6353        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6354
6355    Returns:
6356        Expression: the equivalent expression object.
6357    """
6358    if isinstance(value, Expression):
6359        return maybe_copy(value, copy)
6360    if isinstance(value, str):
6361        return Literal.string(value)
6362    if isinstance(value, bool):
6363        return Boolean(this=value)
6364    if value is None or (isinstance(value, float) and math.isnan(value)):
6365        return NULL
6366    if isinstance(value, numbers.Number):
6367        return Literal.number(value)
6368    if isinstance(value, datetime.datetime):
6369        datetime_literal = Literal.string(
6370            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6371        )
6372        return TimeStrToTime(this=datetime_literal)
6373    if isinstance(value, datetime.date):
6374        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6375        return DateStrToDate(this=date_literal)
6376    if isinstance(value, tuple):
6377        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6378    if isinstance(value, list):
6379        return Array(expressions=[convert(v, copy=copy) for v in value])
6380    if isinstance(value, dict):
6381        return Map(
6382            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6383            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6384        )
6385    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:
6388def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6389    """
6390    Replace children of an expression with the result of a lambda fun(child) -> exp.
6391    """
6392    for k, v in expression.args.items():
6393        is_list_arg = type(v) is list
6394
6395        child_nodes = v if is_list_arg else [v]
6396        new_child_nodes = []
6397
6398        for cn in child_nodes:
6399            if isinstance(cn, Expression):
6400                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6401                    new_child_nodes.append(child_node)
6402                    child_node.parent = expression
6403                    child_node.arg_key = k
6404            else:
6405                new_child_nodes.append(cn)
6406
6407        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]:
6410def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6411    """
6412    Return all table names referenced through columns in an expression.
6413
6414    Example:
6415        >>> import sqlglot
6416        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6417        ['a', 'c']
6418
6419    Args:
6420        expression: expression to find table names.
6421        exclude: a table name to exclude
6422
6423    Returns:
6424        A list of unique names.
6425    """
6426    return {
6427        table
6428        for table in (column.table for column in expression.find_all(Column))
6429        if table and table != exclude
6430    }

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

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:
6465def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6466    """Returns a case normalized table name without quotes.
6467
6468    Args:
6469        table: the table to normalize
6470        dialect: the dialect to use for normalization rules
6471        copy: whether or not to copy the expression.
6472
6473    Examples:
6474        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6475        'A-B.c'
6476    """
6477    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6478
6479    return ".".join(
6480        p.name
6481        for p in normalize_identifiers(
6482            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6483        ).parts
6484    )

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:
6487def replace_tables(
6488    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6489) -> E:
6490    """Replace all tables in expression according to the mapping.
6491
6492    Args:
6493        expression: expression node to be transformed and replaced.
6494        mapping: mapping of table names.
6495        dialect: the dialect of the mapping table
6496        copy: whether or not to copy the expression.
6497
6498    Examples:
6499        >>> from sqlglot import exp, parse_one
6500        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6501        'SELECT * FROM c'
6502
6503    Returns:
6504        The mapped expression.
6505    """
6506
6507    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6508
6509    def _replace_tables(node: Expression) -> Expression:
6510        if isinstance(node, Table):
6511            new_name = mapping.get(normalize_table_name(node, dialect=dialect))
6512
6513            if new_name:
6514                return to_table(
6515                    new_name,
6516                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6517                )
6518        return node
6519
6520    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:
6523def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6524    """Replace placeholders in an expression.
6525
6526    Args:
6527        expression: expression node to be transformed and replaced.
6528        args: positional names that will substitute unnamed placeholders in the given order.
6529        kwargs: keyword arguments that will substitute named placeholders.
6530
6531    Examples:
6532        >>> from sqlglot import exp, parse_one
6533        >>> replace_placeholders(
6534        ...     parse_one("select * from :tbl where ? = ?"),
6535        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6536        ... ).sql()
6537        "SELECT * FROM foo WHERE str_col = 'b'"
6538
6539    Returns:
6540        The mapped expression.
6541    """
6542
6543    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6544        if isinstance(node, Placeholder):
6545            if node.name:
6546                new_name = kwargs.get(node.name)
6547                if new_name:
6548                    return convert(new_name)
6549            else:
6550                try:
6551                    return convert(next(args))
6552                except StopIteration:
6553                    pass
6554        return node
6555
6556    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:
6559def expand(
6560    expression: Expression,
6561    sources: t.Dict[str, Subqueryable],
6562    dialect: DialectType = None,
6563    copy: bool = True,
6564) -> Expression:
6565    """Transforms an expression by expanding all referenced sources into subqueries.
6566
6567    Examples:
6568        >>> from sqlglot import parse_one
6569        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6570        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6571
6572        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6573        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6574
6575    Args:
6576        expression: The expression to expand.
6577        sources: A dictionary of name to Subqueryables.
6578        dialect: The dialect of the sources dict.
6579        copy: Whether or not to copy the expression during transformation. Defaults to True.
6580
6581    Returns:
6582        The transformed expression.
6583    """
6584    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6585
6586    def _expand(node: Expression):
6587        if isinstance(node, Table):
6588            name = normalize_table_name(node, dialect=dialect)
6589            source = sources.get(name)
6590            if source:
6591                subquery = source.subquery(node.alias or name)
6592                subquery.comments = [f"source: {name}"]
6593                return subquery.transform(_expand, copy=False)
6594        return node
6595
6596    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:
6599def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6600    """
6601    Returns a Func expression.
6602
6603    Examples:
6604        >>> func("abs", 5).sql()
6605        'ABS(5)'
6606
6607        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6608        'CAST(5 AS DOUBLE)'
6609
6610    Args:
6611        name: the name of the function to build.
6612        args: the args used to instantiate the function of interest.
6613        dialect: the source dialect.
6614        kwargs: the kwargs used to instantiate the function of interest.
6615
6616    Note:
6617        The arguments `args` and `kwargs` are mutually exclusive.
6618
6619    Returns:
6620        An instance of the function of interest, or an anonymous function, if `name` doesn't
6621        correspond to an existing `sqlglot.expressions.Func` class.
6622    """
6623    if args and kwargs:
6624        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6625
6626    from sqlglot.dialects.dialect import Dialect
6627
6628    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6629    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6630
6631    parser = Dialect.get_or_raise(dialect)().parser()
6632    from_args_list = parser.FUNCTIONS.get(name.upper())
6633
6634    if from_args_list:
6635        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6636    else:
6637        kwargs = kwargs or {"expressions": converted}
6638        function = Anonymous(this=name, **kwargs)
6639
6640    for error_message in function.error_messages(converted):
6641        raise ValueError(error_message)
6642
6643    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:
6646def case(
6647    expression: t.Optional[ExpOrStr] = None,
6648    **opts,
6649) -> Case:
6650    """
6651    Initialize a CASE statement.
6652
6653    Example:
6654        case().when("a = 1", "foo").else_("bar")
6655
6656    Args:
6657        expression: Optionally, the input expression (not all dialects support this)
6658        **opts: Extra keyword arguments for parsing `expression`
6659    """
6660    if expression is not None:
6661        this = maybe_parse(expression, **opts)
6662    else:
6663        this = None
6664    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:
6667def true() -> Boolean:
6668    """
6669    Returns a true Boolean expression.
6670    """
6671    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6674def false() -> Boolean:
6675    """
6676    Returns a false Boolean expression.
6677    """
6678    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6681def null() -> Null:
6682    """
6683    Returns a Null expression.
6684    """
6685    return Null()

Returns a Null expression.

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