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

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)
 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)
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:
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 ""

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

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
272    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
273        if self.comments is None:
274            self.comments = []
275        if comments:
276            for comment in comments:
277                _, *meta = comment.split(SQLGLOT_META)
278                if meta:
279                    for kv in "".join(meta).split(","):
280                        k, *v = kv.split("=")
281                        value = v[0].strip() if v else True
282                        self.meta[k.strip()] = value
283                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
285    def append(self, arg_key: str, value: t.Any) -> None:
286        """
287        Appends value to arg_key if it's a list or sets it as a new list.
288
289        Args:
290            arg_key (str): name of the list expression arg
291            value (Any): value to append to the list
292        """
293        if not isinstance(self.args.get(arg_key), list):
294            self.args[arg_key] = []
295        self.args[arg_key].append(value)
296        self._set_parent(arg_key, value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set(self, arg_key: str, value: Any) -> None:
298    def set(self, arg_key: str, value: t.Any) -> None:
299        """
300        Sets arg_key to value.
301
302        Args:
303            arg_key: name of the expression arg.
304            value: value to set the arg to.
305        """
306        if value is None:
307            self.args.pop(arg_key, None)
308            return
309
310        self.args[arg_key] = value
311        self._set_parent(arg_key, value)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
depth: int

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
332    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
333        """Yields the key and expression for all arguments, exploding list args."""
334        for k, vs in self.args.items():
335            if type(vs) is list:
336                for v in vs:
337                    if hasattr(v, "parent"):
338                        yield k, v
339            else:
340                if hasattr(vs, "parent"):
341                    yield k, vs

Yields the key and expression for all arguments, exploding list args.

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
343    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
344        """
345        Returns the first node in this tree which matches at least one of
346        the specified types.
347
348        Args:
349            expression_types: the expression type(s) to match.
350            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
351
352        Returns:
353            The node which matches the criteria or None if no such node was found.
354        """
355        return next(self.find_all(*expression_types, bfs=bfs), None)

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
357    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
358        """
359        Returns a generator object which visits all nodes in this tree and only
360        yields those that match at least one of the specified expression types.
361
362        Args:
363            expression_types: the expression type(s) to match.
364            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
365
366        Returns:
367            The generator object.
368        """
369        for expression, *_ in self.walk(bfs=bfs):
370            if isinstance(expression, expression_types):
371                yield expression

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
373    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
374        """
375        Returns a nearest parent matching expression_types.
376
377        Args:
378            expression_types: the expression type(s) to match.
379
380        Returns:
381            The parent node.
382        """
383        ancestor = self.parent
384        while ancestor and not isinstance(ancestor, expression_types):
385            ancestor = ancestor.parent
386        return 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:
400    def root(self) -> Expression:
401        """
402        Returns the root expression of this tree.
403        """
404        expression = self
405        while expression.parent:
406            expression = expression.parent
407        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
409    def walk(self, bfs=True, prune=None):
410        """
411        Returns a generator object which visits all nodes in this tree.
412
413        Args:
414            bfs (bool): if set to True the BFS traversal order will be applied,
415                otherwise the DFS traversal will be used instead.
416            prune ((node, parent, arg_key) -> bool): callable that returns True if
417                the generator should stop traversing this branch of the tree.
418
419        Returns:
420            the generator object.
421        """
422        if bfs:
423            yield from self.bfs(prune=prune)
424        else:
425            yield from self.dfs(prune=prune)

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs (bool): if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune ((node, parent, arg_key) -> bool): callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

def dfs(self, parent=None, key=None, prune=None):
427    def dfs(self, parent=None, key=None, prune=None):
428        """
429        Returns a generator object which visits all nodes in this tree in
430        the DFS (Depth-first) order.
431
432        Returns:
433            The generator object.
434        """
435        parent = parent or self.parent
436        yield self, parent, key
437        if prune and prune(self, parent, key):
438            return
439
440        for k, v in self.iter_expressions():
441            yield from v.dfs(self, k, prune)

Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.

Returns:

The generator object.

def bfs(self, prune=None):
443    def bfs(self, prune=None):
444        """
445        Returns a generator object which visits all nodes in this tree in
446        the BFS (Breadth-first) order.
447
448        Returns:
449            The generator object.
450        """
451        queue = deque([(self, self.parent, None)])
452
453        while queue:
454            item, parent, key = queue.popleft()
455
456            yield item, parent, key
457            if prune and prune(item, parent, key):
458                continue
459
460            for k, v in item.iter_expressions():
461                queue.append((v, item, k))

Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.

Returns:

The generator object.

def unnest(self):
463    def unnest(self):
464        """
465        Returns the first non parenthesis child or self.
466        """
467        expression = self
468        while type(expression) is Paren:
469            expression = expression.this
470        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
486    def flatten(self, unnest=True):
487        """
488        Returns a generator which yields child nodes 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

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:
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)

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):
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

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):
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

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:
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

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
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

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]:
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

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):
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)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
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)

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:
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)

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:
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)

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):
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)

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:
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)
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:
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        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
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        )
def is_( self, other: Union[str, Expression]) -> Is:
810    def is_(self, other: ExpOrStr) -> Is:
811        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
813    def like(self, other: ExpOrStr) -> Like:
814        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
816    def ilike(self, other: ExpOrStr) -> ILike:
817        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
819    def eq(self, other: t.Any) -> EQ:
820        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
822    def neq(self, other: t.Any) -> NEQ:
823        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
825    def rlike(self, other: ExpOrStr) -> RegexpLike:
826        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
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
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
915class Condition(Expression):
916    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
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]
selects: List[Expression]
named_selects: List[str]
key = 'derivedtable'
class Unionable(Expression):
 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)
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:
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)

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:
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)

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:
 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)

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):
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 []
selects: List[Expression]
key = 'udtf'
class Cache(Expression):
1011class Cache(Expression):
1012    arg_types = {
1013        "with": False,
1014        "this": True,
1015        "lazy": False,
1016        "options": False,
1017        "expression": False,
1018    }
arg_types = {'with': False, '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 Create(DDL):
1050class Create(DDL):
1051    arg_types = {
1052        "with": False,
1053        "this": True,
1054        "kind": True,
1055        "expression": False,
1056        "exists": False,
1057        "properties": False,
1058        "replace": False,
1059        "unique": False,
1060        "indexes": False,
1061        "no_schema_binding": False,
1062        "begin": False,
1063        "end": False,
1064        "clone": False,
1065    }
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):
1071class Clone(Expression):
1072    arg_types = {
1073        "this": True,
1074        "when": False,
1075        "kind": False,
1076        "shallow": False,
1077        "expression": False,
1078        "copy": False,
1079    }
arg_types = {'this': True, 'when': False, 'kind': False, 'shallow': False, 'expression': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1082class Describe(Expression):
1083    arg_types = {"this": True, "kind": False, "expressions": False}
arg_types = {'this': True, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1086class Kill(Expression):
1087    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1090class Pragma(Expression):
1091    pass
key = 'pragma'
class Set(Expression):
1094class Set(Expression):
1095    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class SetItem(Expression):
1098class SetItem(Expression):
1099    arg_types = {
1100        "this": False,
1101        "expressions": False,
1102        "kind": False,
1103        "collate": False,  # MySQL SET NAMES statement
1104        "global": False,
1105    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1108class Show(Expression):
1109    arg_types = {
1110        "this": True,
1111        "target": False,
1112        "offset": False,
1113        "limit": False,
1114        "like": False,
1115        "where": False,
1116        "db": False,
1117        "scope": False,
1118        "scope_kind": False,
1119        "full": False,
1120        "mutex": False,
1121        "query": False,
1122        "channel": False,
1123        "global": False,
1124        "log": False,
1125        "position": False,
1126        "types": False,
1127    }
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):
1130class UserDefinedFunction(Expression):
1131    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1134class CharacterSet(Expression):
1135    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1138class With(Expression):
1139    arg_types = {"expressions": True, "recursive": False}
1140
1141    @property
1142    def recursive(self) -> bool:
1143        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
key = 'with'
class WithinGroup(Expression):
1146class WithinGroup(Expression):
1147    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1150class CTE(DerivedTable):
1151    arg_types = {"this": True, "alias": True}
arg_types = {'this': True, 'alias': True}
key = 'cte'
class TableAlias(Expression):
1154class TableAlias(Expression):
1155    arg_types = {"this": False, "columns": False}
1156
1157    @property
1158    def columns(self):
1159        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
key = 'tablealias'
class BitString(Condition):
1162class BitString(Condition):
1163    pass
key = 'bitstring'
class HexString(Condition):
1166class HexString(Condition):
1167    pass
key = 'hexstring'
class ByteString(Condition):
1170class ByteString(Condition):
1171    pass
key = 'bytestring'
class RawString(Condition):
1174class RawString(Condition):
1175    pass
key = 'rawstring'
class Column(Condition):
1178class Column(Condition):
1179    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1180
1181    @property
1182    def table(self) -> str:
1183        return self.text("table")
1184
1185    @property
1186    def db(self) -> str:
1187        return self.text("db")
1188
1189    @property
1190    def catalog(self) -> str:
1191        return self.text("catalog")
1192
1193    @property
1194    def output_name(self) -> str:
1195        return self.name
1196
1197    @property
1198    def parts(self) -> t.List[Identifier]:
1199        """Return the parts of a column in order catalog, db, table, name."""
1200        return [
1201            t.cast(Identifier, self.args[part])
1202            for part in ("catalog", "db", "table", "this")
1203            if self.args.get(part)
1204        ]
1205
1206    def to_dot(self) -> Dot | Identifier:
1207        """Converts the column into a dot expression."""
1208        parts = self.parts
1209        parent = self.parent
1210
1211        while parent:
1212            if isinstance(parent, Dot):
1213                parts.append(parent.expression)
1214            parent = parent.parent
1215
1216        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:
1206    def to_dot(self) -> Dot | Identifier:
1207        """Converts the column into a dot expression."""
1208        parts = self.parts
1209        parent = self.parent
1210
1211        while parent:
1212            if isinstance(parent, Dot):
1213                parts.append(parent.expression)
1214            parent = parent.parent
1215
1216        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1219class ColumnPosition(Expression):
1220    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1223class ColumnDef(Expression):
1224    arg_types = {
1225        "this": True,
1226        "kind": False,
1227        "constraints": False,
1228        "exists": False,
1229        "position": False,
1230    }
1231
1232    @property
1233    def constraints(self) -> t.List[ColumnConstraint]:
1234        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):
1237class AlterColumn(Expression):
1238    arg_types = {
1239        "this": True,
1240        "dtype": False,
1241        "collate": False,
1242        "using": False,
1243        "default": False,
1244        "drop": False,
1245    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1248class RenameTable(Expression):
1249    pass
key = 'renametable'
class SwapTable(Expression):
1252class SwapTable(Expression):
1253    pass
key = 'swaptable'
class Comment(Expression):
1256class Comment(Expression):
1257    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):
1260class Comprehension(Expression):
1261    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):
1265class MergeTreeTTLAction(Expression):
1266    arg_types = {
1267        "this": True,
1268        "delete": False,
1269        "recompress": False,
1270        "to_disk": False,
1271        "to_volume": False,
1272    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1276class MergeTreeTTL(Expression):
1277    arg_types = {
1278        "expressions": True,
1279        "where": False,
1280        "group": False,
1281        "aggregates": False,
1282    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1286class IndexConstraintOption(Expression):
1287    arg_types = {
1288        "key_block_size": False,
1289        "using": False,
1290        "parser": False,
1291        "comment": False,
1292        "visible": False,
1293        "engine_attr": False,
1294        "secondary_engine_attr": False,
1295    }
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):
1298class ColumnConstraint(Expression):
1299    arg_types = {"this": False, "kind": True}
1300
1301    @property
1302    def kind(self) -> ColumnConstraintKind:
1303        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1306class ColumnConstraintKind(Expression):
1307    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1310class AutoIncrementColumnConstraint(ColumnConstraintKind):
1311    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1314class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1315    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1318class CaseSpecificColumnConstraint(ColumnConstraintKind):
1319    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1322class CharacterSetColumnConstraint(ColumnConstraintKind):
1323    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1326class CheckColumnConstraint(ColumnConstraintKind):
1327    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1330class ClusteredColumnConstraint(ColumnConstraintKind):
1331    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1334class CollateColumnConstraint(ColumnConstraintKind):
1335    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1338class CommentColumnConstraint(ColumnConstraintKind):
1339    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1342class CompressColumnConstraint(ColumnConstraintKind):
1343    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1346class DateFormatColumnConstraint(ColumnConstraintKind):
1347    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1350class DefaultColumnConstraint(ColumnConstraintKind):
1351    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1354class EncodeColumnConstraint(ColumnConstraintKind):
1355    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1358class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1359    # this: True -> ALWAYS, this: False -> BY DEFAULT
1360    arg_types = {
1361        "this": False,
1362        "expression": False,
1363        "on_null": False,
1364        "start": False,
1365        "increment": False,
1366        "minvalue": False,
1367        "maxvalue": False,
1368        "cycle": False,
1369    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1372class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1373    arg_types = {"start": True, "hidden": False}
arg_types = {'start': True, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1377class IndexColumnConstraint(ColumnConstraintKind):
1378    arg_types = {
1379        "this": False,
1380        "schema": True,
1381        "kind": False,
1382        "index_type": False,
1383        "options": False,
1384    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1387class InlineLengthColumnConstraint(ColumnConstraintKind):
1388    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1391class NonClusteredColumnConstraint(ColumnConstraintKind):
1392    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1395class NotForReplicationColumnConstraint(ColumnConstraintKind):
1396    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1399class NotNullColumnConstraint(ColumnConstraintKind):
1400    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1404class OnUpdateColumnConstraint(ColumnConstraintKind):
1405    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1408class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1409    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1412class TitleColumnConstraint(ColumnConstraintKind):
1413    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1416class UniqueColumnConstraint(ColumnConstraintKind):
1417    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1420class UppercaseColumnConstraint(ColumnConstraintKind):
1421    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1424class PathColumnConstraint(ColumnConstraintKind):
1425    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1430class ComputedColumnConstraint(ColumnConstraintKind):
1431    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1434class Constraint(Expression):
1435    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(Expression):
1438class Delete(Expression):
1439    arg_types = {
1440        "with": False,
1441        "this": False,
1442        "using": False,
1443        "where": False,
1444        "returning": False,
1445        "limit": False,
1446        "tables": False,  # Multiple-Table Syntax (MySQL)
1447    }
1448
1449    def delete(
1450        self,
1451        table: ExpOrStr,
1452        dialect: DialectType = None,
1453        copy: bool = True,
1454        **opts,
1455    ) -> Delete:
1456        """
1457        Create a DELETE expression or replace the table on an existing DELETE expression.
1458
1459        Example:
1460            >>> delete("tbl").sql()
1461            'DELETE FROM tbl'
1462
1463        Args:
1464            table: the table from which to delete.
1465            dialect: the dialect used to parse the input expression.
1466            copy: if `False`, modify this expression instance in-place.
1467            opts: other options to use to parse the input expressions.
1468
1469        Returns:
1470            Delete: the modified expression.
1471        """
1472        return _apply_builder(
1473            expression=table,
1474            instance=self,
1475            arg="this",
1476            dialect=dialect,
1477            into=Table,
1478            copy=copy,
1479            **opts,
1480        )
1481
1482    def where(
1483        self,
1484        *expressions: t.Optional[ExpOrStr],
1485        append: bool = True,
1486        dialect: DialectType = None,
1487        copy: bool = True,
1488        **opts,
1489    ) -> Delete:
1490        """
1491        Append to or set the WHERE expressions.
1492
1493        Example:
1494            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1495            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1496
1497        Args:
1498            *expressions: the SQL code strings to parse.
1499                If an `Expression` instance is passed, it will be used as-is.
1500                Multiple expressions are combined with an AND operator.
1501            append: if `True`, AND the new expressions to any existing expression.
1502                Otherwise, this resets the expression.
1503            dialect: the dialect used to parse the input expressions.
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_conjunction_builder(
1511            *expressions,
1512            instance=self,
1513            arg="where",
1514            append=append,
1515            into=Where,
1516            dialect=dialect,
1517            copy=copy,
1518            **opts,
1519        )
1520
1521    def returning(
1522        self,
1523        expression: ExpOrStr,
1524        dialect: DialectType = None,
1525        copy: bool = True,
1526        **opts,
1527    ) -> Delete:
1528        """
1529        Set the RETURNING expression. Not supported by all dialects.
1530
1531        Example:
1532            >>> delete("tbl").returning("*", dialect="postgres").sql()
1533            'DELETE FROM tbl RETURNING *'
1534
1535        Args:
1536            expression: the SQL code strings to parse.
1537                If an `Expression` instance is passed, it will be used as-is.
1538            dialect: the dialect used to parse the input expressions.
1539            copy: if `False`, modify this expression instance in-place.
1540            opts: other options to use to parse the input expressions.
1541
1542        Returns:
1543            Delete: the modified expression.
1544        """
1545        return _apply_builder(
1546            expression=expression,
1547            instance=self,
1548            arg="returning",
1549            prefix="RETURNING",
1550            dialect=dialect,
1551            copy=copy,
1552            into=Returning,
1553            **opts,
1554        )
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:
1449    def delete(
1450        self,
1451        table: ExpOrStr,
1452        dialect: DialectType = None,
1453        copy: bool = True,
1454        **opts,
1455    ) -> Delete:
1456        """
1457        Create a DELETE expression or replace the table on an existing DELETE expression.
1458
1459        Example:
1460            >>> delete("tbl").sql()
1461            'DELETE FROM tbl'
1462
1463        Args:
1464            table: the table from which to delete.
1465            dialect: the dialect used to parse the input expression.
1466            copy: if `False`, modify this expression instance in-place.
1467            opts: other options to use to parse the input expressions.
1468
1469        Returns:
1470            Delete: the modified expression.
1471        """
1472        return _apply_builder(
1473            expression=table,
1474            instance=self,
1475            arg="this",
1476            dialect=dialect,
1477            into=Table,
1478            copy=copy,
1479            **opts,
1480        )

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:
1482    def where(
1483        self,
1484        *expressions: t.Optional[ExpOrStr],
1485        append: bool = True,
1486        dialect: DialectType = None,
1487        copy: bool = True,
1488        **opts,
1489    ) -> Delete:
1490        """
1491        Append to or set the WHERE expressions.
1492
1493        Example:
1494            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1495            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1496
1497        Args:
1498            *expressions: the SQL code strings to parse.
1499                If an `Expression` instance is passed, it will be used as-is.
1500                Multiple expressions are combined with an AND operator.
1501            append: if `True`, AND the new expressions to any existing expression.
1502                Otherwise, this resets the expression.
1503            dialect: the dialect used to parse the input expressions.
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_conjunction_builder(
1511            *expressions,
1512            instance=self,
1513            arg="where",
1514            append=append,
1515            into=Where,
1516            dialect=dialect,
1517            copy=copy,
1518            **opts,
1519        )

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.

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) -> Delete:
1521    def returning(
1522        self,
1523        expression: ExpOrStr,
1524        dialect: DialectType = None,
1525        copy: bool = True,
1526        **opts,
1527    ) -> Delete:
1528        """
1529        Set the RETURNING expression. Not supported by all dialects.
1530
1531        Example:
1532            >>> delete("tbl").returning("*", dialect="postgres").sql()
1533            'DELETE FROM tbl RETURNING *'
1534
1535        Args:
1536            expression: the SQL code strings to parse.
1537                If an `Expression` instance is passed, it will be used as-is.
1538            dialect: the dialect used to parse the input expressions.
1539            copy: if `False`, modify this expression instance in-place.
1540            opts: other options to use to parse the input expressions.
1541
1542        Returns:
1543            Delete: the modified expression.
1544        """
1545        return _apply_builder(
1546            expression=expression,
1547            instance=self,
1548            arg="returning",
1549            prefix="RETURNING",
1550            dialect=dialect,
1551            copy=copy,
1552            into=Returning,
1553            **opts,
1554        )

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 = 'delete'
class Drop(Expression):
1557class Drop(Expression):
1558    arg_types = {
1559        "this": False,
1560        "kind": False,
1561        "exists": False,
1562        "temporary": False,
1563        "materialized": False,
1564        "cascade": False,
1565        "constraints": False,
1566        "purge": False,
1567    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1570class Filter(Expression):
1571    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1574class Check(Expression):
1575    pass
key = 'check'
class Connect(Expression):
1579class Connect(Expression):
1580    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1583class Prior(Expression):
1584    pass
key = 'prior'
class Directory(Expression):
1587class Directory(Expression):
1588    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1589    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1592class ForeignKey(Expression):
1593    arg_types = {
1594        "expressions": True,
1595        "reference": False,
1596        "delete": False,
1597        "update": False,
1598    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1601class ColumnPrefix(Expression):
1602    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1605class PrimaryKey(Expression):
1606    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1611class Into(Expression):
1612    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1615class From(Expression):
1616    @property
1617    def name(self) -> str:
1618        return self.this.name
1619
1620    @property
1621    def alias_or_name(self) -> str:
1622        return self.this.alias_or_name
name: str
alias_or_name: str
key = 'from'
class Having(Expression):
1625class Having(Expression):
1626    pass
key = 'having'
class Hint(Expression):
1629class Hint(Expression):
1630    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1633class JoinHint(Expression):
1634    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1637class Identifier(Expression):
1638    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1639
1640    @property
1641    def quoted(self) -> bool:
1642        return bool(self.args.get("quoted"))
1643
1644    @property
1645    def hashable_args(self) -> t.Any:
1646        return (self.this, self.quoted)
1647
1648    @property
1649    def output_name(self) -> str:
1650        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):
1654class Opclass(Expression):
1655    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1658class Index(Expression):
1659    arg_types = {
1660        "this": False,
1661        "table": False,
1662        "using": False,
1663        "where": False,
1664        "columns": False,
1665        "unique": False,
1666        "primary": False,
1667        "amp": False,  # teradata
1668        "partition_by": False,  # teradata
1669        "where": False,  # postgres partial indexes
1670    }
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):
1673class Insert(DDL):
1674    arg_types = {
1675        "with": False,
1676        "this": True,
1677        "expression": False,
1678        "conflict": False,
1679        "returning": False,
1680        "overwrite": False,
1681        "exists": False,
1682        "partition": False,
1683        "alternative": False,
1684        "where": False,
1685        "ignore": False,
1686        "by_name": False,
1687    }
1688
1689    def with_(
1690        self,
1691        alias: ExpOrStr,
1692        as_: ExpOrStr,
1693        recursive: t.Optional[bool] = None,
1694        append: bool = True,
1695        dialect: DialectType = None,
1696        copy: bool = True,
1697        **opts,
1698    ) -> Insert:
1699        """
1700        Append to or set the common table expressions.
1701
1702        Example:
1703            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1704            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1705
1706        Args:
1707            alias: the SQL code string to parse as the table name.
1708                If an `Expression` instance is passed, this is used as-is.
1709            as_: the SQL code string to parse as the table expression.
1710                If an `Expression` instance is passed, it will be used as-is.
1711            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1712            append: if `True`, add to any existing expressions.
1713                Otherwise, this resets the expressions.
1714            dialect: the dialect used to parse the input expression.
1715            copy: if `False`, modify this expression instance in-place.
1716            opts: other options to use to parse the input expressions.
1717
1718        Returns:
1719            The modified expression.
1720        """
1721        return _apply_cte_builder(
1722            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1723        )
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:
1689    def with_(
1690        self,
1691        alias: ExpOrStr,
1692        as_: ExpOrStr,
1693        recursive: t.Optional[bool] = None,
1694        append: bool = True,
1695        dialect: DialectType = None,
1696        copy: bool = True,
1697        **opts,
1698    ) -> Insert:
1699        """
1700        Append to or set the common table expressions.
1701
1702        Example:
1703            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1704            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1705
1706        Args:
1707            alias: the SQL code string to parse as the table name.
1708                If an `Expression` instance is passed, this is used as-is.
1709            as_: the SQL code string to parse as the table expression.
1710                If an `Expression` instance is passed, it will be used as-is.
1711            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1712            append: if `True`, add to any existing expressions.
1713                Otherwise, this resets the expressions.
1714            dialect: the dialect used to parse the input expression.
1715            copy: if `False`, modify this expression instance in-place.
1716            opts: other options to use to parse the input expressions.
1717
1718        Returns:
1719            The modified expression.
1720        """
1721        return _apply_cte_builder(
1722            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1723        )

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

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):
2508class WithTableHint(Expression):
2509    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2513class IndexTableHint(Expression):
2514    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class Table(Expression):
2517class Table(Expression):
2518    arg_types = {
2519        "this": True,
2520        "alias": False,
2521        "db": False,
2522        "catalog": False,
2523        "laterals": False,
2524        "joins": False,
2525        "pivots": False,
2526        "hints": False,
2527        "system_time": False,
2528        "version": False,
2529        "format": False,
2530        "pattern": False,
2531        "index": False,
2532        "ordinality": False,
2533    }
2534
2535    @property
2536    def name(self) -> str:
2537        if isinstance(self.this, Func):
2538            return ""
2539        return self.this.name
2540
2541    @property
2542    def db(self) -> str:
2543        return self.text("db")
2544
2545    @property
2546    def catalog(self) -> str:
2547        return self.text("catalog")
2548
2549    @property
2550    def selects(self) -> t.List[Expression]:
2551        return []
2552
2553    @property
2554    def named_selects(self) -> t.List[str]:
2555        return []
2556
2557    @property
2558    def parts(self) -> t.List[Expression]:
2559        """Return the parts of a table in order catalog, db, table."""
2560        parts: t.List[Expression] = []
2561
2562        for arg in ("catalog", "db", "this"):
2563            part = self.args.get(arg)
2564
2565            if isinstance(part, Dot):
2566                parts.extend(part.flatten())
2567            elif isinstance(part, Expression):
2568                parts.append(part)
2569
2570        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):
2573class Union(Subqueryable):
2574    arg_types = {
2575        "with": False,
2576        "this": True,
2577        "expression": True,
2578        "distinct": False,
2579        "by_name": False,
2580        **QUERY_MODIFIERS,
2581    }
2582
2583    def limit(
2584        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2585    ) -> Select:
2586        """
2587        Set the LIMIT expression.
2588
2589        Example:
2590            >>> select("1").union(select("1")).limit(1).sql()
2591            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2592
2593        Args:
2594            expression: the SQL code string to parse.
2595                This can also be an integer.
2596                If a `Limit` instance is passed, this is used as-is.
2597                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2598            dialect: the dialect used to parse the input expression.
2599            copy: if `False`, modify this expression instance in-place.
2600            opts: other options to use to parse the input expressions.
2601
2602        Returns:
2603            The limited subqueryable.
2604        """
2605        return (
2606            select("*")
2607            .from_(self.subquery(alias="_l_0", copy=copy))
2608            .limit(expression, dialect=dialect, copy=False, **opts)
2609        )
2610
2611    def select(
2612        self,
2613        *expressions: t.Optional[ExpOrStr],
2614        append: bool = True,
2615        dialect: DialectType = None,
2616        copy: bool = True,
2617        **opts,
2618    ) -> Union:
2619        """Append to or set the SELECT of the union recursively.
2620
2621        Example:
2622            >>> from sqlglot import parse_one
2623            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2624            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2625
2626        Args:
2627            *expressions: the SQL code strings to parse.
2628                If an `Expression` instance is passed, it will be used as-is.
2629            append: if `True`, add to any existing expressions.
2630                Otherwise, this resets the expressions.
2631            dialect: the dialect used to parse the input expressions.
2632            copy: if `False`, modify this expression instance in-place.
2633            opts: other options to use to parse the input expressions.
2634
2635        Returns:
2636            Union: the modified expression.
2637        """
2638        this = self.copy() if copy else self
2639        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2640        this.expression.unnest().select(
2641            *expressions, append=append, dialect=dialect, copy=False, **opts
2642        )
2643        return this
2644
2645    @property
2646    def named_selects(self) -> t.List[str]:
2647        return self.this.unnest().named_selects
2648
2649    @property
2650    def is_star(self) -> bool:
2651        return self.this.is_star or self.expression.is_star
2652
2653    @property
2654    def selects(self) -> t.List[Expression]:
2655        return self.this.unnest().selects
2656
2657    @property
2658    def left(self) -> Expression:
2659        return self.this
2660
2661    @property
2662    def right(self) -> Expression:
2663        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:
2583    def limit(
2584        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2585    ) -> Select:
2586        """
2587        Set the LIMIT expression.
2588
2589        Example:
2590            >>> select("1").union(select("1")).limit(1).sql()
2591            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2592
2593        Args:
2594            expression: the SQL code string to parse.
2595                This can also be an integer.
2596                If a `Limit` instance is passed, this is used as-is.
2597                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2598            dialect: the dialect used to parse the input expression.
2599            copy: if `False`, modify this expression instance in-place.
2600            opts: other options to use to parse the input expressions.
2601
2602        Returns:
2603            The limited subqueryable.
2604        """
2605        return (
2606            select("*")
2607            .from_(self.subquery(alias="_l_0", copy=copy))
2608            .limit(expression, dialect=dialect, copy=False, **opts)
2609        )

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

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

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

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

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

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

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

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

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

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

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

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

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

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:
3360    def lock(self, update: bool = True, copy: bool = True) -> Select:
3361        """
3362        Set the locking read mode for this expression.
3363
3364        Examples:
3365            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3366            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3367
3368            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3369            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3370
3371        Args:
3372            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3373            copy: if `False`, modify this expression instance in-place.
3374
3375        Returns:
3376            The modified expression.
3377        """
3378        inst = maybe_copy(self, copy)
3379        inst.set("locks", [Lock(update=update)])
3380
3381        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:
3383    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3384        """
3385        Set hints for this expression.
3386
3387        Examples:
3388            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3389            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3390
3391        Args:
3392            hints: The SQL code strings to parse as the hints.
3393                If an `Expression` instance is passed, it will be used as-is.
3394            dialect: The dialect used to parse the hints.
3395            copy: If `False`, modify this expression instance in-place.
3396
3397        Returns:
3398            The modified expression.
3399        """
3400        inst = maybe_copy(self, copy)
3401        inst.set(
3402            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3403        )
3404
3405        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):
3420class Subquery(DerivedTable, Unionable):
3421    arg_types = {
3422        "this": True,
3423        "alias": False,
3424        "with": False,
3425        **QUERY_MODIFIERS,
3426    }
3427
3428    def unnest(self):
3429        """
3430        Returns the first non subquery.
3431        """
3432        expression = self
3433        while isinstance(expression, Subquery):
3434            expression = expression.this
3435        return expression
3436
3437    def unwrap(self) -> Subquery:
3438        expression = self
3439        while expression.same_parent and expression.is_wrapper:
3440            expression = t.cast(Subquery, expression.parent)
3441        return expression
3442
3443    @property
3444    def is_wrapper(self) -> bool:
3445        """
3446        Whether this Subquery acts as a simple wrapper around another expression.
3447
3448        SELECT * FROM (((SELECT * FROM t)))
3449                      ^
3450                      This corresponds to a "wrapper" Subquery node
3451        """
3452        return all(v is None for k, v in self.args.items() if k != "this")
3453
3454    @property
3455    def is_star(self) -> bool:
3456        return self.this.is_star
3457
3458    @property
3459    def output_name(self) -> str:
3460        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):
3428    def unnest(self):
3429        """
3430        Returns the first non subquery.
3431        """
3432        expression = self
3433        while isinstance(expression, Subquery):
3434            expression = expression.this
3435        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3437    def unwrap(self) -> Subquery:
3438        expression = self
3439        while expression.same_parent and expression.is_wrapper:
3440            expression = t.cast(Subquery, expression.parent)
3441        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):
3463class TableSample(Expression):
3464    arg_types = {
3465        "this": False,
3466        "expressions": False,
3467        "method": False,
3468        "bucket_numerator": False,
3469        "bucket_denominator": False,
3470        "bucket_field": False,
3471        "percent": False,
3472        "rows": False,
3473        "size": False,
3474        "seed": False,
3475        "kind": False,
3476    }
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):
3479class Tag(Expression):
3480    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3481
3482    arg_types = {
3483        "this": False,
3484        "prefix": False,
3485        "postfix": False,
3486    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3491class Pivot(Expression):
3492    arg_types = {
3493        "this": False,
3494        "alias": False,
3495        "expressions": False,
3496        "field": False,
3497        "unpivot": False,
3498        "using": False,
3499        "group": False,
3500        "columns": False,
3501        "include_nulls": False,
3502    }
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):
3505class Window(Condition):
3506    arg_types = {
3507        "this": True,
3508        "partition_by": False,
3509        "order": False,
3510        "spec": False,
3511        "alias": False,
3512        "over": False,
3513        "first": False,
3514    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3517class WindowSpec(Expression):
3518    arg_types = {
3519        "kind": False,
3520        "start": False,
3521        "start_side": False,
3522        "end": False,
3523        "end_side": False,
3524    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3527class Where(Expression):
3528    pass
key = 'where'
class Star(Expression):
3531class Star(Expression):
3532    arg_types = {"except": False, "replace": False}
3533
3534    @property
3535    def name(self) -> str:
3536        return "*"
3537
3538    @property
3539    def output_name(self) -> str:
3540        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):
3543class Parameter(Condition):
3544    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3547class SessionParameter(Condition):
3548    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3551class Placeholder(Condition):
3552    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3555class Null(Condition):
3556    arg_types: t.Dict[str, t.Any] = {}
3557
3558    @property
3559    def name(self) -> str:
3560        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
key = 'null'
class Boolean(Condition):
3563class Boolean(Condition):
3564    pass
key = 'boolean'
class DataTypeParam(Expression):
3567class DataTypeParam(Expression):
3568    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3571class DataType(Expression):
3572    arg_types = {
3573        "this": True,
3574        "expressions": False,
3575        "nested": False,
3576        "values": False,
3577        "prefix": False,
3578        "kind": False,
3579    }
3580
3581    class Type(AutoName):
3582        ARRAY = auto()
3583        BIGDECIMAL = auto()
3584        BIGINT = auto()
3585        BIGSERIAL = auto()
3586        BINARY = auto()
3587        BIT = auto()
3588        BOOLEAN = auto()
3589        CHAR = auto()
3590        DATE = auto()
3591        DATEMULTIRANGE = auto()
3592        DATERANGE = auto()
3593        DATETIME = auto()
3594        DATETIME64 = auto()
3595        DECIMAL = auto()
3596        DOUBLE = auto()
3597        ENUM = auto()
3598        ENUM8 = auto()
3599        ENUM16 = auto()
3600        FIXEDSTRING = auto()
3601        FLOAT = auto()
3602        GEOGRAPHY = auto()
3603        GEOMETRY = auto()
3604        HLLSKETCH = auto()
3605        HSTORE = auto()
3606        IMAGE = auto()
3607        INET = auto()
3608        INT = auto()
3609        INT128 = auto()
3610        INT256 = auto()
3611        INT4MULTIRANGE = auto()
3612        INT4RANGE = auto()
3613        INT8MULTIRANGE = auto()
3614        INT8RANGE = auto()
3615        INTERVAL = auto()
3616        IPADDRESS = auto()
3617        IPPREFIX = auto()
3618        JSON = auto()
3619        JSONB = auto()
3620        LONGBLOB = auto()
3621        LONGTEXT = auto()
3622        LOWCARDINALITY = auto()
3623        MAP = auto()
3624        MEDIUMBLOB = auto()
3625        MEDIUMINT = auto()
3626        MEDIUMTEXT = auto()
3627        MONEY = auto()
3628        NCHAR = auto()
3629        NESTED = auto()
3630        NULL = auto()
3631        NULLABLE = auto()
3632        NUMMULTIRANGE = auto()
3633        NUMRANGE = auto()
3634        NVARCHAR = auto()
3635        OBJECT = auto()
3636        ROWVERSION = auto()
3637        SERIAL = auto()
3638        SET = auto()
3639        SMALLINT = auto()
3640        SMALLMONEY = auto()
3641        SMALLSERIAL = auto()
3642        STRUCT = auto()
3643        SUPER = auto()
3644        TEXT = auto()
3645        TINYBLOB = auto()
3646        TINYTEXT = auto()
3647        TIME = auto()
3648        TIMETZ = auto()
3649        TIMESTAMP = auto()
3650        TIMESTAMPLTZ = auto()
3651        TIMESTAMPTZ = auto()
3652        TIMESTAMP_S = auto()
3653        TIMESTAMP_MS = auto()
3654        TIMESTAMP_NS = auto()
3655        TINYINT = auto()
3656        TSMULTIRANGE = auto()
3657        TSRANGE = auto()
3658        TSTZMULTIRANGE = auto()
3659        TSTZRANGE = auto()
3660        UBIGINT = auto()
3661        UINT = auto()
3662        UINT128 = auto()
3663        UINT256 = auto()
3664        UMEDIUMINT = auto()
3665        UDECIMAL = auto()
3666        UNIQUEIDENTIFIER = auto()
3667        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3668        USERDEFINED = "USER-DEFINED"
3669        USMALLINT = auto()
3670        UTINYINT = auto()
3671        UUID = auto()
3672        VARBINARY = auto()
3673        VARCHAR = auto()
3674        VARIANT = auto()
3675        XML = auto()
3676        YEAR = auto()
3677
3678    TEXT_TYPES = {
3679        Type.CHAR,
3680        Type.NCHAR,
3681        Type.VARCHAR,
3682        Type.NVARCHAR,
3683        Type.TEXT,
3684    }
3685
3686    INTEGER_TYPES = {
3687        Type.INT,
3688        Type.TINYINT,
3689        Type.SMALLINT,
3690        Type.BIGINT,
3691        Type.INT128,
3692        Type.INT256,
3693        Type.BIT,
3694    }
3695
3696    FLOAT_TYPES = {
3697        Type.FLOAT,
3698        Type.DOUBLE,
3699    }
3700
3701    NUMERIC_TYPES = {
3702        *INTEGER_TYPES,
3703        *FLOAT_TYPES,
3704    }
3705
3706    TEMPORAL_TYPES = {
3707        Type.TIME,
3708        Type.TIMETZ,
3709        Type.TIMESTAMP,
3710        Type.TIMESTAMPTZ,
3711        Type.TIMESTAMPLTZ,
3712        Type.TIMESTAMP_S,
3713        Type.TIMESTAMP_MS,
3714        Type.TIMESTAMP_NS,
3715        Type.DATE,
3716        Type.DATETIME,
3717        Type.DATETIME64,
3718    }
3719
3720    @classmethod
3721    def build(
3722        cls,
3723        dtype: str | DataType | DataType.Type,
3724        dialect: DialectType = None,
3725        udt: bool = False,
3726        **kwargs,
3727    ) -> DataType:
3728        """
3729        Constructs a DataType object.
3730
3731        Args:
3732            dtype: the data type of interest.
3733            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3734            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3735                DataType, thus creating a user-defined type.
3736            kawrgs: additional arguments to pass in the constructor of DataType.
3737
3738        Returns:
3739            The constructed DataType object.
3740        """
3741        from sqlglot import parse_one
3742
3743        if isinstance(dtype, str):
3744            if dtype.upper() == "UNKNOWN":
3745                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3746
3747            try:
3748                data_type_exp = parse_one(
3749                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3750                )
3751            except ParseError:
3752                if udt:
3753                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3754                raise
3755        elif isinstance(dtype, DataType.Type):
3756            data_type_exp = DataType(this=dtype)
3757        elif isinstance(dtype, DataType):
3758            return dtype
3759        else:
3760            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3761
3762        return DataType(**{**data_type_exp.args, **kwargs})
3763
3764    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
3765        """
3766        Checks whether this DataType matches one of the provided data types. Nested types or precision
3767        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3768
3769        Args:
3770            dtypes: the data types to compare this DataType to.
3771
3772        Returns:
3773            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3774        """
3775        for dtype in dtypes:
3776            other = DataType.build(dtype, udt=True)
3777
3778            if (
3779                other.expressions
3780                or self.this == DataType.Type.USERDEFINED
3781                or other.this == DataType.Type.USERDEFINED
3782            ):
3783                matches = self == other
3784            else:
3785                matches = self.this == other.this
3786
3787            if matches:
3788                return True
3789        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.BIT: 'BIT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.BIT: 'BIT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.TINYINT: 'TINYINT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>}
TEMPORAL_TYPES = {<Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME: 'DATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>}
@classmethod
def build( cls, dtype: str | DataType | DataType.Type, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, **kwargs) -> DataType:
3720    @classmethod
3721    def build(
3722        cls,
3723        dtype: str | DataType | DataType.Type,
3724        dialect: DialectType = None,
3725        udt: bool = False,
3726        **kwargs,
3727    ) -> DataType:
3728        """
3729        Constructs a DataType object.
3730
3731        Args:
3732            dtype: the data type of interest.
3733            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3734            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3735                DataType, thus creating a user-defined type.
3736            kawrgs: additional arguments to pass in the constructor of DataType.
3737
3738        Returns:
3739            The constructed DataType object.
3740        """
3741        from sqlglot import parse_one
3742
3743        if isinstance(dtype, str):
3744            if dtype.upper() == "UNKNOWN":
3745                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3746
3747            try:
3748                data_type_exp = parse_one(
3749                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3750                )
3751            except ParseError:
3752                if udt:
3753                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3754                raise
3755        elif isinstance(dtype, DataType.Type):
3756            data_type_exp = DataType(this=dtype)
3757        elif isinstance(dtype, DataType):
3758            return dtype
3759        else:
3760            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3761
3762        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: str | DataType | DataType.Type) -> bool:
3764    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
3765        """
3766        Checks whether this DataType matches one of the provided data types. Nested types or precision
3767        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3768
3769        Args:
3770            dtypes: the data types to compare this DataType to.
3771
3772        Returns:
3773            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3774        """
3775        for dtype in dtypes:
3776            other = DataType.build(dtype, udt=True)
3777
3778            if (
3779                other.expressions
3780                or self.this == DataType.Type.USERDEFINED
3781                or other.this == DataType.Type.USERDEFINED
3782            ):
3783                matches = self == other
3784            else:
3785                matches = self.this == other.this
3786
3787            if matches:
3788                return True
3789        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):
3581    class Type(AutoName):
3582        ARRAY = auto()
3583        BIGDECIMAL = auto()
3584        BIGINT = auto()
3585        BIGSERIAL = auto()
3586        BINARY = auto()
3587        BIT = auto()
3588        BOOLEAN = auto()
3589        CHAR = auto()
3590        DATE = auto()
3591        DATEMULTIRANGE = auto()
3592        DATERANGE = auto()
3593        DATETIME = auto()
3594        DATETIME64 = auto()
3595        DECIMAL = auto()
3596        DOUBLE = auto()
3597        ENUM = auto()
3598        ENUM8 = auto()
3599        ENUM16 = auto()
3600        FIXEDSTRING = auto()
3601        FLOAT = auto()
3602        GEOGRAPHY = auto()
3603        GEOMETRY = auto()
3604        HLLSKETCH = auto()
3605        HSTORE = auto()
3606        IMAGE = auto()
3607        INET = auto()
3608        INT = auto()
3609        INT128 = auto()
3610        INT256 = auto()
3611        INT4MULTIRANGE = auto()
3612        INT4RANGE = auto()
3613        INT8MULTIRANGE = auto()
3614        INT8RANGE = auto()
3615        INTERVAL = auto()
3616        IPADDRESS = auto()
3617        IPPREFIX = auto()
3618        JSON = auto()
3619        JSONB = auto()
3620        LONGBLOB = auto()
3621        LONGTEXT = auto()
3622        LOWCARDINALITY = auto()
3623        MAP = auto()
3624        MEDIUMBLOB = auto()
3625        MEDIUMINT = auto()
3626        MEDIUMTEXT = auto()
3627        MONEY = auto()
3628        NCHAR = auto()
3629        NESTED = auto()
3630        NULL = auto()
3631        NULLABLE = auto()
3632        NUMMULTIRANGE = auto()
3633        NUMRANGE = auto()
3634        NVARCHAR = auto()
3635        OBJECT = auto()
3636        ROWVERSION = auto()
3637        SERIAL = auto()
3638        SET = auto()
3639        SMALLINT = auto()
3640        SMALLMONEY = auto()
3641        SMALLSERIAL = auto()
3642        STRUCT = auto()
3643        SUPER = auto()
3644        TEXT = auto()
3645        TINYBLOB = auto()
3646        TINYTEXT = auto()
3647        TIME = auto()
3648        TIMETZ = auto()
3649        TIMESTAMP = auto()
3650        TIMESTAMPLTZ = auto()
3651        TIMESTAMPTZ = auto()
3652        TIMESTAMP_S = auto()
3653        TIMESTAMP_MS = auto()
3654        TIMESTAMP_NS = auto()
3655        TINYINT = auto()
3656        TSMULTIRANGE = auto()
3657        TSRANGE = auto()
3658        TSTZMULTIRANGE = auto()
3659        TSTZRANGE = auto()
3660        UBIGINT = auto()
3661        UINT = auto()
3662        UINT128 = auto()
3663        UINT256 = auto()
3664        UMEDIUMINT = auto()
3665        UDECIMAL = auto()
3666        UNIQUEIDENTIFIER = auto()
3667        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3668        USERDEFINED = "USER-DEFINED"
3669        USMALLINT = auto()
3670        UTINYINT = auto()
3671        UUID = auto()
3672        VARBINARY = auto()
3673        VARCHAR = auto()
3674        VARIANT = auto()
3675        XML = auto()
3676        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
class PseudoType(DataType):
3793class PseudoType(DataType):
3794    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3798class ObjectIdentifier(DataType):
3799    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3803class SubqueryPredicate(Predicate):
3804    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3807class All(SubqueryPredicate):
3808    pass
key = 'all'
class Any(SubqueryPredicate):
3811class Any(SubqueryPredicate):
3812    pass
key = 'any'
class Exists(SubqueryPredicate):
3815class Exists(SubqueryPredicate):
3816    pass
key = 'exists'
class Command(Expression):
3821class Command(Expression):
3822    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3825class Transaction(Expression):
3826    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3829class Commit(Expression):
3830    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3833class Rollback(Expression):
3834    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3837class AlterTable(Expression):
3838    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):
3841class AddConstraint(Expression):
3842    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3845class DropPartition(Expression):
3846    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3850class Binary(Condition):
3851    arg_types = {"this": True, "expression": True}
3852
3853    @property
3854    def left(self) -> Expression:
3855        return self.this
3856
3857    @property
3858    def right(self) -> Expression:
3859        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
right: Expression
key = 'binary'
class Add(Binary):
3862class Add(Binary):
3863    pass
key = 'add'
class Connector(Binary):
3866class Connector(Binary):
3867    pass
key = 'connector'
class And(Connector):
3870class And(Connector):
3871    pass
key = 'and'
class Or(Connector):
3874class Or(Connector):
3875    pass
key = 'or'
class BitwiseAnd(Binary):
3878class BitwiseAnd(Binary):
3879    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3882class BitwiseLeftShift(Binary):
3883    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3886class BitwiseOr(Binary):
3887    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3890class BitwiseRightShift(Binary):
3891    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3894class BitwiseXor(Binary):
3895    pass
key = 'bitwisexor'
class Div(Binary):
3898class Div(Binary):
3899    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):
3902class Overlaps(Binary):
3903    pass
key = 'overlaps'
class Dot(Binary):
3906class Dot(Binary):
3907    @property
3908    def name(self) -> str:
3909        return self.expression.name
3910
3911    @property
3912    def output_name(self) -> str:
3913        return self.name
3914
3915    @classmethod
3916    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3917        """Build a Dot object with a sequence of expressions."""
3918        if len(expressions) < 2:
3919            raise ValueError(f"Dot requires >= 2 expressions.")
3920
3921        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
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:
3915    @classmethod
3916    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3917        """Build a Dot object with a sequence of expressions."""
3918        if len(expressions) < 2:
3919            raise ValueError(f"Dot requires >= 2 expressions.")
3920
3921        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

key = 'dot'
class DPipe(Binary):
3924class DPipe(Binary):
3925    pass
key = 'dpipe'
class SafeDPipe(DPipe):
3928class SafeDPipe(DPipe):
3929    pass
key = 'safedpipe'
class EQ(Binary, Predicate):
3932class EQ(Binary, Predicate):
3933    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3936class NullSafeEQ(Binary, Predicate):
3937    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3940class NullSafeNEQ(Binary, Predicate):
3941    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3945class PropertyEQ(Binary):
3946    pass
key = 'propertyeq'
class Distance(Binary):
3949class Distance(Binary):
3950    pass
key = 'distance'
class Escape(Binary):
3953class Escape(Binary):
3954    pass
key = 'escape'
class Glob(Binary, Predicate):
3957class Glob(Binary, Predicate):
3958    pass
key = 'glob'
class GT(Binary, Predicate):
3961class GT(Binary, Predicate):
3962    pass
key = 'gt'
class GTE(Binary, Predicate):
3965class GTE(Binary, Predicate):
3966    pass
key = 'gte'
class ILike(Binary, Predicate):
3969class ILike(Binary, Predicate):
3970    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3973class ILikeAny(Binary, Predicate):
3974    pass
key = 'ilikeany'
class IntDiv(Binary):
3977class IntDiv(Binary):
3978    pass
key = 'intdiv'
class Is(Binary, Predicate):
3981class Is(Binary, Predicate):
3982    pass
key = 'is'
class Kwarg(Binary):
3985class Kwarg(Binary):
3986    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
3989class Like(Binary, Predicate):
3990    pass
key = 'like'
class LikeAny(Binary, Predicate):
3993class LikeAny(Binary, Predicate):
3994    pass
key = 'likeany'
class LT(Binary, Predicate):
3997class LT(Binary, Predicate):
3998    pass
key = 'lt'
class LTE(Binary, Predicate):
4001class LTE(Binary, Predicate):
4002    pass
key = 'lte'
class Mod(Binary):
4005class Mod(Binary):
4006    pass
key = 'mod'
class Mul(Binary):
4009class Mul(Binary):
4010    pass
key = 'mul'
class NEQ(Binary, Predicate):
4013class NEQ(Binary, Predicate):
4014    pass
key = 'neq'
class SimilarTo(Binary, Predicate):
4017class SimilarTo(Binary, Predicate):
4018    pass
key = 'similarto'
class Slice(Binary):
4021class Slice(Binary):
4022    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4025class Sub(Binary):
4026    pass
key = 'sub'
class ArrayOverlaps(Binary):
4029class ArrayOverlaps(Binary):
4030    pass
key = 'arrayoverlaps'
class Unary(Condition):
4035class Unary(Condition):
4036    pass
key = 'unary'
class BitwiseNot(Unary):
4039class BitwiseNot(Unary):
4040    pass
key = 'bitwisenot'
class Not(Unary):
4043class Not(Unary):
4044    pass
key = 'not'
class Paren(Unary):
4047class Paren(Unary):
4048    arg_types = {"this": True, "with": False}
4049
4050    @property
4051    def output_name(self) -> str:
4052        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):
4055class Neg(Unary):
4056    pass
key = 'neg'
class Alias(Expression):
4059class Alias(Expression):
4060    arg_types = {"this": True, "alias": False}
4061
4062    @property
4063    def output_name(self) -> str:
4064        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):
4067class Aliases(Expression):
4068    arg_types = {"this": True, "expressions": True}
4069
4070    @property
4071    def aliases(self):
4072        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
4075class AtTimeZone(Expression):
4076    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4079class Between(Predicate):
4080    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4083class Bracket(Condition):
4084    arg_types = {"this": True, "expressions": True}
4085
4086    @property
4087    def output_name(self) -> str:
4088        if len(self.expressions) == 1:
4089            return self.expressions[0].output_name
4090
4091        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):
4094class SafeBracket(Bracket):
4095    """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):
4098class Distinct(Expression):
4099    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4102class In(Predicate):
4103    arg_types = {
4104        "this": True,
4105        "expressions": False,
4106        "query": False,
4107        "unnest": False,
4108        "field": False,
4109        "is_global": False,
4110    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4114class ForIn(Expression):
4115    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4118class TimeUnit(Expression):
4119    """Automatically converts unit arg into a var."""
4120
4121    arg_types = {"unit": False}
4122
4123    UNABBREVIATED_UNIT_NAME = {
4124        "d": "day",
4125        "h": "hour",
4126        "m": "minute",
4127        "ms": "millisecond",
4128        "ns": "nanosecond",
4129        "q": "quarter",
4130        "s": "second",
4131        "us": "microsecond",
4132        "w": "week",
4133        "y": "year",
4134    }
4135
4136    VAR_LIKE = (Column, Literal, Var)
4137
4138    def __init__(self, **args):
4139        unit = args.get("unit")
4140        if isinstance(unit, self.VAR_LIKE):
4141            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4142        elif isinstance(unit, Week):
4143            unit.set("this", Var(this=unit.this.name))
4144
4145        super().__init__(**args)
4146
4147    @property
4148    def unit(self) -> t.Optional[Var]:
4149        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4138    def __init__(self, **args):
4139        unit = args.get("unit")
4140        if isinstance(unit, self.VAR_LIKE):
4141            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4142        elif isinstance(unit, Week):
4143            unit.set("this", Var(this=unit.this.name))
4144
4145        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):
4152class IntervalOp(TimeUnit):
4153    arg_types = {"unit": True, "expression": True}
4154
4155    def interval(self):
4156        return Interval(
4157            this=self.expression.copy(),
4158            unit=self.unit.copy(),
4159        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4155    def interval(self):
4156        return Interval(
4157            this=self.expression.copy(),
4158            unit=self.unit.copy(),
4159        )
key = 'intervalop'
class IntervalSpan(DataType):
4165class IntervalSpan(DataType):
4166    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4169class Interval(TimeUnit):
4170    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4173class IgnoreNulls(Expression):
4174    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4177class RespectNulls(Expression):
4178    pass
key = 'respectnulls'
class Func(Condition):
4182class Func(Condition):
4183    """
4184    The base class for all function expressions.
4185
4186    Attributes:
4187        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4188            treated as a variable length argument and the argument's value will be stored as a list.
4189        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4190            for this function expression. These values are used to map this node to a name during parsing
4191            as well as to provide the function's name during SQL string generation. By default the SQL
4192            name is set to the expression's class name transformed to snake case.
4193    """
4194
4195    is_var_len_args = False
4196
4197    @classmethod
4198    def from_arg_list(cls, args):
4199        if cls.is_var_len_args:
4200            all_arg_keys = list(cls.arg_types)
4201            # If this function supports variable length argument treat the last argument as such.
4202            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4203            num_non_var = len(non_var_len_arg_keys)
4204
4205            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4206            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4207        else:
4208            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4209
4210        return cls(**args_dict)
4211
4212    @classmethod
4213    def sql_names(cls):
4214        if cls is Func:
4215            raise NotImplementedError(
4216                "SQL name is only supported by concrete function implementations"
4217            )
4218        if "_sql_names" not in cls.__dict__:
4219            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4220        return cls._sql_names
4221
4222    @classmethod
4223    def sql_name(cls):
4224        return cls.sql_names()[0]
4225
4226    @classmethod
4227    def default_parser_mappings(cls):
4228        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):
4197    @classmethod
4198    def from_arg_list(cls, args):
4199        if cls.is_var_len_args:
4200            all_arg_keys = list(cls.arg_types)
4201            # If this function supports variable length argument treat the last argument as such.
4202            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4203            num_non_var = len(non_var_len_arg_keys)
4204
4205            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4206            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4207        else:
4208            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4209
4210        return cls(**args_dict)
@classmethod
def sql_names(cls):
4212    @classmethod
4213    def sql_names(cls):
4214        if cls is Func:
4215            raise NotImplementedError(
4216                "SQL name is only supported by concrete function implementations"
4217            )
4218        if "_sql_names" not in cls.__dict__:
4219            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4220        return cls._sql_names
@classmethod
def sql_name(cls):
4222    @classmethod
4223    def sql_name(cls):
4224        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4226    @classmethod
4227    def default_parser_mappings(cls):
4228        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4231class AggFunc(Func):
4232    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4235class ParameterizedAgg(AggFunc):
4236    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4239class Abs(Func):
4240    pass
key = 'abs'
class ArgMax(AggFunc):
4243class ArgMax(AggFunc):
4244    arg_types = {"this": True, "expression": True, "count": False}
4245    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4248class ArgMin(AggFunc):
4249    arg_types = {"this": True, "expression": True, "count": False}
4250    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4253class ApproxTopK(AggFunc):
4254    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4257class Flatten(Func):
4258    pass
key = 'flatten'
class Transform(Func):
4262class Transform(Func):
4263    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4266class Anonymous(Func):
4267    arg_types = {"this": True, "expressions": False}
4268    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4273class Hll(AggFunc):
4274    arg_types = {"this": True, "expressions": False}
4275    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4278class ApproxDistinct(AggFunc):
4279    arg_types = {"this": True, "accuracy": False}
4280    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4283class Array(Func):
4284    arg_types = {"expressions": False}
4285    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4289class ToChar(Func):
4290    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tochar'
class GenerateSeries(Func):
4293class GenerateSeries(Func):
4294    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4297class ArrayAgg(AggFunc):
4298    pass
key = 'arrayagg'
class ArrayAll(Func):
4301class ArrayAll(Func):
4302    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4305class ArrayAny(Func):
4306    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4309class ArrayConcat(Func):
4310    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4311    arg_types = {"this": True, "expressions": False}
4312    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4315class ArrayContains(Binary, Func):
4316    pass
key = 'arraycontains'
class ArrayContained(Binary):
4319class ArrayContained(Binary):
4320    pass
key = 'arraycontained'
class ArrayFilter(Func):
4323class ArrayFilter(Func):
4324    arg_types = {"this": True, "expression": True}
4325    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4328class ArrayJoin(Func):
4329    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4332class ArraySize(Func):
4333    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4336class ArraySort(Func):
4337    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4340class ArraySum(Func):
4341    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4344class ArrayUnionAgg(AggFunc):
4345    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4348class Avg(AggFunc):
4349    pass
key = 'avg'
class AnyValue(AggFunc):
4352class AnyValue(AggFunc):
4353    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):
4356class First(Func):
4357    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4360class Last(Func):
4361    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4364class Case(Func):
4365    arg_types = {"this": False, "ifs": True, "default": False}
4366
4367    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4368        instance = maybe_copy(self, copy)
4369        instance.append(
4370            "ifs",
4371            If(
4372                this=maybe_parse(condition, copy=copy, **opts),
4373                true=maybe_parse(then, copy=copy, **opts),
4374            ),
4375        )
4376        return instance
4377
4378    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4379        instance = maybe_copy(self, copy)
4380        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4381        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:
4367    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4368        instance = maybe_copy(self, copy)
4369        instance.append(
4370            "ifs",
4371            If(
4372                this=maybe_parse(condition, copy=copy, **opts),
4373                true=maybe_parse(then, copy=copy, **opts),
4374            ),
4375        )
4376        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4378    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4379        instance = maybe_copy(self, copy)
4380        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4381        return instance
key = 'case'
class Cast(Func):
4384class Cast(Func):
4385    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4386
4387    @property
4388    def name(self) -> str:
4389        return self.this.name
4390
4391    @property
4392    def to(self) -> DataType:
4393        return self.args["to"]
4394
4395    @property
4396    def output_name(self) -> str:
4397        return self.name
4398
4399    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4400        """
4401        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4402        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4403        array<int> != array<float>.
4404
4405        Args:
4406            dtypes: the data types to compare this Cast's DataType to.
4407
4408        Returns:
4409            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4410        """
4411        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: str | DataType | DataType.Type) -> bool:
4399    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4400        """
4401        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4402        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4403        array<int> != array<float>.
4404
4405        Args:
4406            dtypes: the data types to compare this Cast's DataType to.
4407
4408        Returns:
4409            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4410        """
4411        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):
4414class TryCast(Cast):
4415    pass
key = 'trycast'
class CastToStrType(Func):
4418class CastToStrType(Func):
4419    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4422class Collate(Binary, Func):
4423    pass
key = 'collate'
class Ceil(Func):
4426class Ceil(Func):
4427    arg_types = {"this": True, "decimals": False}
4428    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4431class Coalesce(Func):
4432    arg_types = {"this": True, "expressions": False}
4433    is_var_len_args = True
4434    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4437class Chr(Func):
4438    arg_types = {"this": True, "charset": False, "expressions": False}
4439    is_var_len_args = True
4440    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4443class Concat(Func):
4444    arg_types = {"expressions": True}
4445    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4448class SafeConcat(Concat):
4449    pass
key = 'safeconcat'
class ConcatWs(Concat):
4452class ConcatWs(Concat):
4453    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4456class Count(AggFunc):
4457    arg_types = {"this": False, "expressions": False}
4458    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4461class CountIf(AggFunc):
4462    pass
key = 'countif'
class CurrentDate(Func):
4465class CurrentDate(Func):
4466    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4469class CurrentDatetime(Func):
4470    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4473class CurrentTime(Func):
4474    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4477class CurrentTimestamp(Func):
4478    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4481class CurrentUser(Func):
4482    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4485class DateAdd(Func, IntervalOp):
4486    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4489class DateSub(Func, IntervalOp):
4490    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4493class DateDiff(Func, TimeUnit):
4494    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4495    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4498class DateTrunc(Func):
4499    arg_types = {"unit": True, "this": True, "zone": False}
4500
4501    @property
4502    def unit(self) -> Expression:
4503        return self.args["unit"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4506class DatetimeAdd(Func, IntervalOp):
4507    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4510class DatetimeSub(Func, IntervalOp):
4511    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4514class DatetimeDiff(Func, TimeUnit):
4515    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4518class DatetimeTrunc(Func, TimeUnit):
4519    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4522class DayOfWeek(Func):
4523    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4526class DayOfMonth(Func):
4527    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4530class DayOfYear(Func):
4531    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4534class ToDays(Func):
4535    pass
key = 'todays'
class WeekOfYear(Func):
4538class WeekOfYear(Func):
4539    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4542class MonthsBetween(Func):
4543    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4546class LastDateOfMonth(Func):
4547    pass
key = 'lastdateofmonth'
class Extract(Func):
4550class Extract(Func):
4551    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4554class Timestamp(Func):
4555    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4558class TimestampAdd(Func, TimeUnit):
4559    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4562class TimestampSub(Func, TimeUnit):
4563    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4566class TimestampDiff(Func, TimeUnit):
4567    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4570class TimestampTrunc(Func, TimeUnit):
4571    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4574class TimeAdd(Func, TimeUnit):
4575    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4578class TimeSub(Func, TimeUnit):
4579    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4582class TimeDiff(Func, TimeUnit):
4583    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4586class TimeTrunc(Func, TimeUnit):
4587    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4590class DateFromParts(Func):
4591    _sql_names = ["DATEFROMPARTS"]
4592    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4595class DateStrToDate(Func):
4596    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4599class DateToDateStr(Func):
4600    pass
key = 'datetodatestr'
class DateToDi(Func):
4603class DateToDi(Func):
4604    pass
key = 'datetodi'
class Date(Func):
4608class Date(Func):
4609    arg_types = {"this": False, "zone": False, "expressions": False}
4610    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4613class Day(Func):
4614    pass
key = 'day'
class Decode(Func):
4617class Decode(Func):
4618    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4621class DiToDate(Func):
4622    pass
key = 'ditodate'
class Encode(Func):
4625class Encode(Func):
4626    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4629class Exp(Func):
4630    pass
key = 'exp'
class Explode(Func):
4634class Explode(Func):
4635    arg_types = {"this": True, "expressions": False}
4636    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4639class ExplodeOuter(Explode):
4640    pass
key = 'explodeouter'
class Posexplode(Explode):
4643class Posexplode(Explode):
4644    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4647class PosexplodeOuter(Posexplode):
4648    pass
key = 'posexplodeouter'
class Floor(Func):
4651class Floor(Func):
4652    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4655class FromBase64(Func):
4656    pass
key = 'frombase64'
class ToBase64(Func):
4659class ToBase64(Func):
4660    pass
key = 'tobase64'
class Greatest(Func):
4663class Greatest(Func):
4664    arg_types = {"this": True, "expressions": False}
4665    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4668class GroupConcat(AggFunc):
4669    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4672class Hex(Func):
4673    pass
key = 'hex'
class Xor(Connector, Func):
4676class Xor(Connector, Func):
4677    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4680class If(Func):
4681    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4684class Nullif(Func):
4685    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4688class Initcap(Func):
4689    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4692class IsNan(Func):
4693    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class FormatJson(Expression):
4696class FormatJson(Expression):
4697    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4700class JSONKeyValue(Expression):
4701    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4704class JSONObject(Func):
4705    arg_types = {
4706        "expressions": False,
4707        "null_handling": False,
4708        "unique_keys": False,
4709        "return_type": False,
4710        "encoding": False,
4711    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4715class JSONArray(Func):
4716    arg_types = {
4717        "expressions": True,
4718        "null_handling": False,
4719        "return_type": False,
4720        "strict": False,
4721    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4725class JSONArrayAgg(Func):
4726    arg_types = {
4727        "this": True,
4728        "order": False,
4729        "null_handling": False,
4730        "return_type": False,
4731        "strict": False,
4732    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4737class JSONColumnDef(Expression):
4738    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):
4741class JSONSchema(Expression):
4742    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4746class JSONTable(Func):
4747    arg_types = {
4748        "this": True,
4749        "schema": True,
4750        "path": False,
4751        "error_handling": False,
4752        "empty_handling": False,
4753    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4756class OpenJSONColumnDef(Expression):
4757    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):
4760class OpenJSON(Func):
4761    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4764class JSONBContains(Binary):
4765    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4768class JSONExtract(Binary, Func):
4769    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4772class JSONExtractScalar(JSONExtract):
4773    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4776class JSONBExtract(JSONExtract):
4777    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4780class JSONBExtractScalar(JSONExtract):
4781    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4784class JSONFormat(Func):
4785    arg_types = {"this": False, "options": False}
4786    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4790class JSONArrayContains(Binary, Predicate, Func):
4791    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4794class ParseJSON(Func):
4795    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4796    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4797    arg_types = {"this": True, "expressions": False}
4798    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
4801class Least(Func):
4802    arg_types = {"this": True, "expressions": False}
4803    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4806class Left(Func):
4807    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4814class Length(Func):
4815    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4818class Levenshtein(Func):
4819    arg_types = {
4820        "this": True,
4821        "expression": False,
4822        "ins_cost": False,
4823        "del_cost": False,
4824        "sub_cost": False,
4825    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4828class Ln(Func):
4829    pass
key = 'ln'
class Log(Func):
4832class Log(Func):
4833    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4836class Log2(Func):
4837    pass
key = 'log2'
class Log10(Func):
4840class Log10(Func):
4841    pass
key = 'log10'
class LogicalOr(AggFunc):
4844class LogicalOr(AggFunc):
4845    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4848class LogicalAnd(AggFunc):
4849    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4852class Lower(Func):
4853    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4856class Map(Func):
4857    arg_types = {"keys": False, "values": False}
4858
4859    @property
4860    def keys(self) -> t.List[Expression]:
4861        keys = self.args.get("keys")
4862        return keys.expressions if keys else []
4863
4864    @property
4865    def values(self) -> t.List[Expression]:
4866        values = self.args.get("values")
4867        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
values: List[Expression]
key = 'map'
class MapFromEntries(Func):
4870class MapFromEntries(Func):
4871    pass
key = 'mapfromentries'
class StarMap(Func):
4874class StarMap(Func):
4875    pass
key = 'starmap'
class VarMap(Func):
4878class VarMap(Func):
4879    arg_types = {"keys": True, "values": True}
4880    is_var_len_args = True
4881
4882    @property
4883    def keys(self) -> t.List[Expression]:
4884        return self.args["keys"].expressions
4885
4886    @property
4887    def values(self) -> t.List[Expression]:
4888        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):
4892class MatchAgainst(Func):
4893    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4896class Max(AggFunc):
4897    arg_types = {"this": True, "expressions": False}
4898    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4901class MD5(Func):
4902    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4906class MD5Digest(Func):
4907    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4910class Min(AggFunc):
4911    arg_types = {"this": True, "expressions": False}
4912    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4915class Month(Func):
4916    pass
key = 'month'
class Nvl2(Func):
4919class Nvl2(Func):
4920    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
4924class Predict(Func):
4925    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
4928class Pow(Binary, Func):
4929    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4932class PercentileCont(AggFunc):
4933    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4936class PercentileDisc(AggFunc):
4937    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4940class Quantile(AggFunc):
4941    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4944class ApproxQuantile(Quantile):
4945    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):
4948class RangeN(Func):
4949    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4952class ReadCSV(Func):
4953    _sql_names = ["READ_CSV"]
4954    is_var_len_args = True
4955    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4958class Reduce(Func):
4959    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):
4962class RegexpExtract(Func):
4963    arg_types = {
4964        "this": True,
4965        "expression": True,
4966        "position": False,
4967        "occurrence": False,
4968        "parameters": False,
4969        "group": False,
4970    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
4973class RegexpReplace(Func):
4974    arg_types = {
4975        "this": True,
4976        "expression": True,
4977        "replacement": True,
4978        "position": False,
4979        "occurrence": False,
4980        "parameters": False,
4981        "modifiers": False,
4982    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
4985class RegexpLike(Binary, Func):
4986    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
4989class RegexpILike(Binary, Func):
4990    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
4995class RegexpSplit(Func):
4996    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
4999class Repeat(Func):
5000    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5003class Round(Func):
5004    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5007class RowNumber(Func):
5008    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5011class SafeDivide(Func):
5012    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SetAgg(AggFunc):
5015class SetAgg(AggFunc):
5016    pass
key = 'setagg'
class SHA(Func):
5019class SHA(Func):
5020    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5023class SHA2(Func):
5024    _sql_names = ["SHA2"]
5025    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5028class SortArray(Func):
5029    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5032class Split(Func):
5033    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5038class Substring(Func):
5039    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5042class StandardHash(Func):
5043    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5046class StartsWith(Func):
5047    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5048    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5051class StrPosition(Func):
5052    arg_types = {
5053        "this": True,
5054        "substr": True,
5055        "position": False,
5056        "instance": False,
5057    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5060class StrToDate(Func):
5061    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5064class StrToTime(Func):
5065    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5070class StrToUnix(Func):
5071    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5076class StrToMap(Func):
5077    arg_types = {
5078        "this": True,
5079        "pair_delim": False,
5080        "key_value_delim": False,
5081        "duplicate_resolution_callback": False,
5082    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5085class NumberToStr(Func):
5086    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5089class FromBase(Func):
5090    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5093class Struct(Func):
5094    arg_types = {"expressions": False}
5095    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5098class StructExtract(Func):
5099    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5104class Stuff(Func):
5105    _sql_names = ["STUFF", "INSERT"]
5106    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):
5109class Sum(AggFunc):
5110    pass
key = 'sum'
class Sqrt(Func):
5113class Sqrt(Func):
5114    pass
key = 'sqrt'
class Stddev(AggFunc):
5117class Stddev(AggFunc):
5118    pass
key = 'stddev'
class StddevPop(AggFunc):
5121class StddevPop(AggFunc):
5122    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5125class StddevSamp(AggFunc):
5126    pass
key = 'stddevsamp'
class TimeToStr(Func):
5129class TimeToStr(Func):
5130    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5133class TimeToTimeStr(Func):
5134    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5137class TimeToUnix(Func):
5138    pass
key = 'timetounix'
class TimeStrToDate(Func):
5141class TimeStrToDate(Func):
5142    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5145class TimeStrToTime(Func):
5146    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5149class TimeStrToUnix(Func):
5150    pass
key = 'timestrtounix'
class Trim(Func):
5153class Trim(Func):
5154    arg_types = {
5155        "this": True,
5156        "expression": False,
5157        "position": False,
5158        "collation": False,
5159    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5162class TsOrDsAdd(Func, TimeUnit):
5163    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsadd'
class TsOrDsToDateStr(Func):
5166class TsOrDsToDateStr(Func):
5167    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5170class TsOrDsToDate(Func):
5171    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
5174class TsOrDiToDi(Func):
5175    pass
key = 'tsorditodi'
class Unhex(Func):
5178class Unhex(Func):
5179    pass
key = 'unhex'
class UnixToStr(Func):
5182class UnixToStr(Func):
5183    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5188class UnixToTime(Func):
5189    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5190
5191    SECONDS = Literal.string("seconds")
5192    MILLIS = Literal.string("millis")
5193    MICROS = Literal.string("micros")
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)
key = 'unixtotime'
class UnixToTimeStr(Func):
5196class UnixToTimeStr(Func):
5197    pass
key = 'unixtotimestr'
class Upper(Func):
5200class Upper(Func):
5201    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5204class Variance(AggFunc):
5205    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5208class VariancePop(AggFunc):
5209    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5212class Week(Func):
5213    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5216class XMLTable(Func):
5217    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):
5220class Year(Func):
5221    pass
key = 'year'
class Use(Expression):
5224class Use(Expression):
5225    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5228class Merge(Expression):
5229    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):
5232class When(Func):
5233    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):
5238class NextValueFor(Func):
5239    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 '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 '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 'SetAgg'>, <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 '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:
5276def maybe_parse(
5277    sql_or_expression: ExpOrStr,
5278    *,
5279    into: t.Optional[IntoType] = None,
5280    dialect: DialectType = None,
5281    prefix: t.Optional[str] = None,
5282    copy: bool = False,
5283    **opts,
5284) -> Expression:
5285    """Gracefully handle a possible string or expression.
5286
5287    Example:
5288        >>> maybe_parse("1")
5289        (LITERAL this: 1, is_string: False)
5290        >>> maybe_parse(to_identifier("x"))
5291        (IDENTIFIER this: x, quoted: False)
5292
5293    Args:
5294        sql_or_expression: the SQL code string or an expression
5295        into: the SQLGlot Expression to parse into
5296        dialect: the dialect used to parse the input expressions (in the case that an
5297            input expression is a SQL string).
5298        prefix: a string to prefix the sql with before it gets parsed
5299            (automatically includes a space)
5300        copy: whether or not to copy the expression.
5301        **opts: other options to use to parse the input expressions (again, in the case
5302            that an input expression is a SQL string).
5303
5304    Returns:
5305        Expression: the parsed or given expression.
5306    """
5307    if isinstance(sql_or_expression, Expression):
5308        if copy:
5309            return sql_or_expression.copy()
5310        return sql_or_expression
5311
5312    if sql_or_expression is None:
5313        raise ParseError(f"SQL cannot be None")
5314
5315    import sqlglot
5316
5317    sql = str(sql_or_expression)
5318    if prefix:
5319        sql = f"{prefix} {sql}"
5320
5321    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):
5334def maybe_copy(instance, copy=True):
5335    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:
5516def union(
5517    left: ExpOrStr,
5518    right: ExpOrStr,
5519    distinct: bool = True,
5520    dialect: DialectType = None,
5521    copy: bool = True,
5522    **opts,
5523) -> Union:
5524    """
5525    Initializes a syntax tree from one UNION expression.
5526
5527    Example:
5528        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5529        'SELECT * FROM foo UNION SELECT * FROM bla'
5530
5531    Args:
5532        left: the SQL code string corresponding to the left-hand side.
5533            If an `Expression` instance is passed, it will be used as-is.
5534        right: the SQL code string corresponding to the right-hand side.
5535            If an `Expression` instance is passed, it will be used as-is.
5536        distinct: set the DISTINCT flag if and only if this is true.
5537        dialect: the dialect used to parse the input expression.
5538        copy: whether or not to copy the expression.
5539        opts: other options to use to parse the input expressions.
5540
5541    Returns:
5542        The new Union instance.
5543    """
5544    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5545    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5546
5547    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:
5550def intersect(
5551    left: ExpOrStr,
5552    right: ExpOrStr,
5553    distinct: bool = True,
5554    dialect: DialectType = None,
5555    copy: bool = True,
5556    **opts,
5557) -> Intersect:
5558    """
5559    Initializes a syntax tree from one INTERSECT expression.
5560
5561    Example:
5562        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5563        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5564
5565    Args:
5566        left: the SQL code string corresponding to the left-hand side.
5567            If an `Expression` instance is passed, it will be used as-is.
5568        right: the SQL code string corresponding to the right-hand side.
5569            If an `Expression` instance is passed, it will be used as-is.
5570        distinct: set the DISTINCT flag if and only if this is true.
5571        dialect: the dialect used to parse the input expression.
5572        copy: whether or not to copy the expression.
5573        opts: other options to use to parse the input expressions.
5574
5575    Returns:
5576        The new Intersect instance.
5577    """
5578    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5579    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5580
5581    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:
5584def except_(
5585    left: ExpOrStr,
5586    right: ExpOrStr,
5587    distinct: bool = True,
5588    dialect: DialectType = None,
5589    copy: bool = True,
5590    **opts,
5591) -> Except:
5592    """
5593    Initializes a syntax tree from one EXCEPT expression.
5594
5595    Example:
5596        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5597        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5598
5599    Args:
5600        left: the SQL code string corresponding to the left-hand side.
5601            If an `Expression` instance is passed, it will be used as-is.
5602        right: the SQL code string corresponding to the right-hand side.
5603            If an `Expression` instance is passed, it will be used as-is.
5604        distinct: set the DISTINCT flag if and only if this is true.
5605        dialect: the dialect used to parse the input expression.
5606        copy: whether or not to copy the expression.
5607        opts: other options to use to parse the input expressions.
5608
5609    Returns:
5610        The new Except instance.
5611    """
5612    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5613    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5614
5615    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:
5618def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5619    """
5620    Initializes a syntax tree from one or multiple SELECT expressions.
5621
5622    Example:
5623        >>> select("col1", "col2").from_("tbl").sql()
5624        'SELECT col1, col2 FROM tbl'
5625
5626    Args:
5627        *expressions: the SQL code string to parse as the expressions of a
5628            SELECT statement. If an Expression instance is passed, this is used as-is.
5629        dialect: the dialect used to parse the input expressions (in the case that an
5630            input expression is a SQL string).
5631        **opts: other options to use to parse the input expressions (again, in the case
5632            that an input expression is a SQL string).
5633
5634    Returns:
5635        Select: the syntax tree for the SELECT statement.
5636    """
5637    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:
5640def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5641    """
5642    Initializes a syntax tree from a FROM expression.
5643
5644    Example:
5645        >>> from_("tbl").select("col1", "col2").sql()
5646        'SELECT col1, col2 FROM tbl'
5647
5648    Args:
5649        *expression: the SQL code string to parse as the FROM expressions of a
5650            SELECT statement. If an Expression instance is passed, this is used as-is.
5651        dialect: the dialect used to parse the input expression (in the case that the
5652            input expression is a SQL string).
5653        **opts: other options to use to parse the input expressions (again, in the case
5654            that the input expression is a SQL string).
5655
5656    Returns:
5657        Select: the syntax tree for the SELECT statement.
5658    """
5659    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:
5662def update(
5663    table: str | Table,
5664    properties: dict,
5665    where: t.Optional[ExpOrStr] = None,
5666    from_: t.Optional[ExpOrStr] = None,
5667    dialect: DialectType = None,
5668    **opts,
5669) -> Update:
5670    """
5671    Creates an update statement.
5672
5673    Example:
5674        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5675        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5676
5677    Args:
5678        *properties: dictionary of properties to set which are
5679            auto converted to sql objects eg None -> NULL
5680        where: sql conditional parsed into a WHERE statement
5681        from_: sql statement parsed into a FROM statement
5682        dialect: the dialect used to parse the input expressions.
5683        **opts: other options to use to parse the input expressions.
5684
5685    Returns:
5686        Update: the syntax tree for the UPDATE statement.
5687    """
5688    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5689    update_expr.set(
5690        "expressions",
5691        [
5692            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5693            for k, v in properties.items()
5694        ],
5695    )
5696    if from_:
5697        update_expr.set(
5698            "from",
5699            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5700        )
5701    if isinstance(where, Condition):
5702        where = Where(this=where)
5703    if where:
5704        update_expr.set(
5705            "where",
5706            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5707        )
5708    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:
5711def delete(
5712    table: ExpOrStr,
5713    where: t.Optional[ExpOrStr] = None,
5714    returning: t.Optional[ExpOrStr] = None,
5715    dialect: DialectType = None,
5716    **opts,
5717) -> Delete:
5718    """
5719    Builds a delete statement.
5720
5721    Example:
5722        >>> delete("my_table", where="id > 1").sql()
5723        'DELETE FROM my_table WHERE id > 1'
5724
5725    Args:
5726        where: sql conditional parsed into a WHERE statement
5727        returning: sql conditional parsed into a RETURNING statement
5728        dialect: the dialect used to parse the input expressions.
5729        **opts: other options to use to parse the input expressions.
5730
5731    Returns:
5732        Delete: the syntax tree for the DELETE statement.
5733    """
5734    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5735    if where:
5736        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5737    if returning:
5738        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5739    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, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
5742def insert(
5743    expression: ExpOrStr,
5744    into: ExpOrStr,
5745    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5746    overwrite: t.Optional[bool] = None,
5747    dialect: DialectType = None,
5748    copy: bool = True,
5749    **opts,
5750) -> Insert:
5751    """
5752    Builds an INSERT statement.
5753
5754    Example:
5755        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5756        'INSERT INTO tbl VALUES (1, 2, 3)'
5757
5758    Args:
5759        expression: the sql string or expression of the INSERT statement
5760        into: the tbl to insert data to.
5761        columns: optionally the table's column names.
5762        overwrite: whether to INSERT OVERWRITE or not.
5763        dialect: the dialect used to parse the input expressions.
5764        copy: whether or not to copy the expression.
5765        **opts: other options to use to parse the input expressions.
5766
5767    Returns:
5768        Insert: the syntax tree for the INSERT statement.
5769    """
5770    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5771    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5772
5773    if columns:
5774        this = _apply_list_builder(
5775            *columns,
5776            instance=Schema(this=this),
5777            arg="expressions",
5778            into=Identifier,
5779            copy=False,
5780            dialect=dialect,
5781            **opts,
5782        )
5783
5784    return Insert(this=this, expression=expr, overwrite=overwrite)

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.
  • 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:
5787def condition(
5788    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5789) -> Condition:
5790    """
5791    Initialize a logical condition expression.
5792
5793    Example:
5794        >>> condition("x=1").sql()
5795        'x = 1'
5796
5797        This is helpful for composing larger logical syntax trees:
5798        >>> where = condition("x=1")
5799        >>> where = where.and_("y=1")
5800        >>> Select().from_("tbl").select("*").where(where).sql()
5801        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5802
5803    Args:
5804        *expression: the SQL code string to parse.
5805            If an Expression instance is passed, this is used as-is.
5806        dialect: the dialect used to parse the input expression (in the case that the
5807            input expression is a SQL string).
5808        copy: Whether or not to copy `expression` (only applies to expressions).
5809        **opts: other options to use to parse the input expressions (again, in the case
5810            that the input expression is a SQL string).
5811
5812    Returns:
5813        The new Condition instance
5814    """
5815    return maybe_parse(
5816        expression,
5817        into=Condition,
5818        dialect=dialect,
5819        copy=copy,
5820        **opts,
5821    )

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:
5824def and_(
5825    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5826) -> Condition:
5827    """
5828    Combine multiple conditions with an AND logical operator.
5829
5830    Example:
5831        >>> and_("x=1", and_("y=1", "z=1")).sql()
5832        'x = 1 AND (y = 1 AND z = 1)'
5833
5834    Args:
5835        *expressions: the SQL code strings to parse.
5836            If an Expression instance is passed, this is used as-is.
5837        dialect: the dialect used to parse the input expression.
5838        copy: whether or not to copy `expressions` (only applies to Expressions).
5839        **opts: other options to use to parse the input expressions.
5840
5841    Returns:
5842        And: the new condition
5843    """
5844    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:
5847def or_(
5848    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5849) -> Condition:
5850    """
5851    Combine multiple conditions with an OR logical operator.
5852
5853    Example:
5854        >>> or_("x=1", or_("y=1", "z=1")).sql()
5855        'x = 1 OR (y = 1 OR z = 1)'
5856
5857    Args:
5858        *expressions: the SQL code strings to parse.
5859            If an Expression instance is passed, this is used as-is.
5860        dialect: the dialect used to parse the input expression.
5861        copy: whether or not to copy `expressions` (only applies to Expressions).
5862        **opts: other options to use to parse the input expressions.
5863
5864    Returns:
5865        Or: the new condition
5866    """
5867    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:
5870def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5871    """
5872    Wrap a condition with a NOT operator.
5873
5874    Example:
5875        >>> not_("this_suit='black'").sql()
5876        "NOT this_suit = 'black'"
5877
5878    Args:
5879        expression: the SQL code string to parse.
5880            If an Expression instance is passed, this is used as-is.
5881        dialect: the dialect used to parse the input expression.
5882        copy: whether to copy the expression or not.
5883        **opts: other options to use to parse the input expressions.
5884
5885    Returns:
5886        The new condition.
5887    """
5888    this = condition(
5889        expression,
5890        dialect=dialect,
5891        copy=copy,
5892        **opts,
5893    )
5894    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:
5897def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5898    """
5899    Wrap an expression in parentheses.
5900
5901    Example:
5902        >>> paren("5 + 3").sql()
5903        '(5 + 3)'
5904
5905    Args:
5906        expression: the SQL code string to parse.
5907            If an Expression instance is passed, this is used as-is.
5908        copy: whether to copy the expression or not.
5909
5910    Returns:
5911        The wrapped expression.
5912    """
5913    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):
5931def to_identifier(name, quoted=None, copy=True):
5932    """Builds an identifier.
5933
5934    Args:
5935        name: The name to turn into an identifier.
5936        quoted: Whether or not force quote the identifier.
5937        copy: Whether or not to copy name if it's an Identifier.
5938
5939    Returns:
5940        The identifier ast node.
5941    """
5942
5943    if name is None:
5944        return None
5945
5946    if isinstance(name, Identifier):
5947        identifier = maybe_copy(name, copy)
5948    elif isinstance(name, str):
5949        identifier = Identifier(
5950            this=name,
5951            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
5952        )
5953    else:
5954        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
5955    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:
5958def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
5959    """
5960    Parses a given string into an identifier.
5961
5962    Args:
5963        name: The name to parse into an identifier.
5964        dialect: The dialect to parse against.
5965
5966    Returns:
5967        The identifier ast node.
5968    """
5969    try:
5970        expression = maybe_parse(name, dialect=dialect, into=Identifier)
5971    except ParseError:
5972        expression = to_identifier(name)
5973
5974    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:
5980def to_interval(interval: str | Literal) -> Interval:
5981    """Builds an interval expression from a string like '1 day' or '5 months'."""
5982    if isinstance(interval, Literal):
5983        if not interval.is_string:
5984            raise ValueError("Invalid interval string.")
5985
5986        interval = interval.this
5987
5988    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
5989
5990    if not interval_parts:
5991        raise ValueError("Invalid interval string.")
5992
5993    return Interval(
5994        this=Literal.string(interval_parts.group(1)),
5995        unit=Var(this=interval_parts.group(2)),
5996    )

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, **kwargs) -> Optional[Table]:
6009def to_table(
6010    sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs
6011) -> t.Optional[Table]:
6012    """
6013    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6014    If a table is passed in then that table is returned.
6015
6016    Args:
6017        sql_path: a `[catalog].[schema].[table]` string.
6018        dialect: the source dialect according to which the table name will be parsed.
6019        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6020
6021    Returns:
6022        A table expression.
6023    """
6024    if sql_path is None or isinstance(sql_path, Table):
6025        return sql_path
6026    if not isinstance(sql_path, str):
6027        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6028
6029    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6030    if table:
6031        for k, v in kwargs.items():
6032            table.set(k, v)
6033
6034    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.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
6037def to_column(sql_path: str | Column, **kwargs) -> Column:
6038    """
6039    Create a column from a `[table].[column]` sql path. Schema is optional.
6040
6041    If a column is passed in then that column is returned.
6042
6043    Args:
6044        sql_path: `[table].[column]` string
6045    Returns:
6046        Table: A column expression
6047    """
6048    if sql_path is None or isinstance(sql_path, Column):
6049        return sql_path
6050    if not isinstance(sql_path, str):
6051        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6052    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):
6055def alias_(
6056    expression: ExpOrStr,
6057    alias: str | Identifier,
6058    table: bool | t.Sequence[str | Identifier] = False,
6059    quoted: t.Optional[bool] = None,
6060    dialect: DialectType = None,
6061    copy: bool = True,
6062    **opts,
6063):
6064    """Create an Alias expression.
6065
6066    Example:
6067        >>> alias_('foo', 'bar').sql()
6068        'foo AS bar'
6069
6070        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6071        '(SELECT 1, 2) AS bar(a, b)'
6072
6073    Args:
6074        expression: the SQL code strings to parse.
6075            If an Expression instance is passed, this is used as-is.
6076        alias: the alias name to use. If the name has
6077            special characters it is quoted.
6078        table: Whether or not to create a table alias, can also be a list of columns.
6079        quoted: whether or not to quote the alias
6080        dialect: the dialect used to parse the input expression.
6081        copy: Whether or not to copy the expression.
6082        **opts: other options to use to parse the input expressions.
6083
6084    Returns:
6085        Alias: the aliased expression
6086    """
6087    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6088    alias = to_identifier(alias, quoted=quoted)
6089
6090    if table:
6091        table_alias = TableAlias(this=alias)
6092        exp.set("alias", table_alias)
6093
6094        if not isinstance(table, bool):
6095            for column in table:
6096                table_alias.append("columns", to_identifier(column, quoted=quoted))
6097
6098        return exp
6099
6100    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6101    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6102    # for the complete Window expression.
6103    #
6104    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6105
6106    if "alias" in exp.arg_types and not isinstance(exp, Window):
6107        exp.set("alias", alias)
6108        return exp
6109    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:
6112def subquery(
6113    expression: ExpOrStr,
6114    alias: t.Optional[Identifier | str] = None,
6115    dialect: DialectType = None,
6116    **opts,
6117) -> Select:
6118    """
6119    Build a subquery expression.
6120
6121    Example:
6122        >>> subquery('select x from tbl', 'bar').select('x').sql()
6123        'SELECT x FROM (SELECT x FROM tbl) AS bar'
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.
6129        dialect: the dialect used to parse the input expression.
6130        **opts: other options to use to parse the input expressions.
6131
6132    Returns:
6133        A new Select instance with the subquery expression included.
6134    """
6135
6136    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6137    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:
6140def column(
6141    col: str | Identifier,
6142    table: t.Optional[str | Identifier] = None,
6143    db: t.Optional[str | Identifier] = None,
6144    catalog: t.Optional[str | Identifier] = None,
6145    quoted: t.Optional[bool] = None,
6146) -> Column:
6147    """
6148    Build a Column.
6149
6150    Args:
6151        col: Column name.
6152        table: Table name.
6153        db: Database name.
6154        catalog: Catalog name.
6155        quoted: Whether to force quotes on the column's identifiers.
6156
6157    Returns:
6158        The new Column instance.
6159    """
6160    return Column(
6161        this=to_identifier(col, quoted=quoted),
6162        table=to_identifier(table, quoted=quoted),
6163        db=to_identifier(db, quoted=quoted),
6164        catalog=to_identifier(catalog, quoted=quoted),
6165    )

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: str | DataType | DataType.Type, **opts) -> Cast:
6168def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast:
6169    """Cast an expression to a data type.
6170
6171    Example:
6172        >>> cast('x + 1', 'int').sql()
6173        'CAST(x + 1 AS INT)'
6174
6175    Args:
6176        expression: The expression to cast.
6177        to: The datatype to cast to.
6178
6179    Returns:
6180        The new Cast instance.
6181    """
6182    expression = maybe_parse(expression, **opts)
6183    data_type = DataType.build(to, **opts)
6184    expression = Cast(this=expression, to=data_type)
6185    expression.type = data_type
6186    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:
6189def table_(
6190    table: Identifier | str,
6191    db: t.Optional[Identifier | str] = None,
6192    catalog: t.Optional[Identifier | str] = None,
6193    quoted: t.Optional[bool] = None,
6194    alias: t.Optional[Identifier | str] = None,
6195) -> Table:
6196    """Build a Table.
6197
6198    Args:
6199        table: Table name.
6200        db: Database name.
6201        catalog: Catalog name.
6202        quote: Whether to force quotes on the table's identifiers.
6203        alias: Table's alias.
6204
6205    Returns:
6206        The new Table instance.
6207    """
6208    return Table(
6209        this=to_identifier(table, quoted=quoted) if table else None,
6210        db=to_identifier(db, quoted=quoted) if db else None,
6211        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6212        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6213    )

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:
6216def values(
6217    values: t.Iterable[t.Tuple[t.Any, ...]],
6218    alias: t.Optional[str] = None,
6219    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6220) -> Values:
6221    """Build VALUES statement.
6222
6223    Example:
6224        >>> values([(1, '2')]).sql()
6225        "VALUES (1, '2')"
6226
6227    Args:
6228        values: values statements that will be converted to SQL
6229        alias: optional alias
6230        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6231         If either are provided then an alias is also required.
6232
6233    Returns:
6234        Values: the Values expression object
6235    """
6236    if columns and not alias:
6237        raise ValueError("Alias is required when providing columns")
6238
6239    return Values(
6240        expressions=[convert(tup) for tup in values],
6241        alias=(
6242            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6243            if columns
6244            else (TableAlias(this=to_identifier(alias)) if alias else None)
6245        ),
6246    )

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:
6249def var(name: t.Optional[ExpOrStr]) -> Var:
6250    """Build a SQL variable.
6251
6252    Example:
6253        >>> repr(var('x'))
6254        '(VAR this: x)'
6255
6256        >>> repr(var(column('x', table='y')))
6257        '(VAR this: x)'
6258
6259    Args:
6260        name: The name of the var or an expression who's name will become the var.
6261
6262    Returns:
6263        The new variable node.
6264    """
6265    if not name:
6266        raise ValueError("Cannot convert empty name into var.")
6267
6268    if isinstance(name, Expression):
6269        name = name.name
6270    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:
6273def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6274    """Build ALTER TABLE... RENAME... expression
6275
6276    Args:
6277        old_name: The old name of the table
6278        new_name: The new name of the table
6279
6280    Returns:
6281        Alter table expression
6282    """
6283    old_table = to_table(old_name)
6284    new_table = to_table(new_name)
6285    return AlterTable(
6286        this=old_table,
6287        actions=[
6288            RenameTable(this=new_table),
6289        ],
6290    )

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:
6293def convert(value: t.Any, copy: bool = False) -> Expression:
6294    """Convert a python value into an expression object.
6295
6296    Raises an error if a conversion is not possible.
6297
6298    Args:
6299        value: A python object.
6300        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6301
6302    Returns:
6303        Expression: the equivalent expression object.
6304    """
6305    if isinstance(value, Expression):
6306        return maybe_copy(value, copy)
6307    if isinstance(value, str):
6308        return Literal.string(value)
6309    if isinstance(value, bool):
6310        return Boolean(this=value)
6311    if value is None or (isinstance(value, float) and math.isnan(value)):
6312        return NULL
6313    if isinstance(value, numbers.Number):
6314        return Literal.number(value)
6315    if isinstance(value, datetime.datetime):
6316        datetime_literal = Literal.string(
6317            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6318        )
6319        return TimeStrToTime(this=datetime_literal)
6320    if isinstance(value, datetime.date):
6321        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6322        return DateStrToDate(this=date_literal)
6323    if isinstance(value, tuple):
6324        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6325    if isinstance(value, list):
6326        return Array(expressions=[convert(v, copy=copy) for v in value])
6327    if isinstance(value, dict):
6328        return Map(
6329            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6330            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6331        )
6332    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:
6335def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6336    """
6337    Replace children of an expression with the result of a lambda fun(child) -> exp.
6338    """
6339    for k, v in expression.args.items():
6340        is_list_arg = type(v) is list
6341
6342        child_nodes = v if is_list_arg else [v]
6343        new_child_nodes = []
6344
6345        for cn in child_nodes:
6346            if isinstance(cn, Expression):
6347                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6348                    new_child_nodes.append(child_node)
6349                    child_node.parent = expression
6350                    child_node.arg_key = k
6351            else:
6352                new_child_nodes.append(cn)
6353
6354        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]:
6357def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6358    """
6359    Return all table names referenced through columns in an expression.
6360
6361    Example:
6362        >>> import sqlglot
6363        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6364        ['a', 'c']
6365
6366    Args:
6367        expression: expression to find table names.
6368        exclude: a table name to exclude
6369
6370    Returns:
6371        A list of unique names.
6372    """
6373    return {
6374        table
6375        for table in (column.table for column in expression.find_all(Column))
6376        if table and table != exclude
6377    }

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) -> str:
6380def table_name(table: Table | str, dialect: DialectType = None) -> str:
6381    """Get the full name of a table as a string.
6382
6383    Args:
6384        table: Table expression node or string.
6385        dialect: The dialect to generate the table name for.
6386
6387    Examples:
6388        >>> from sqlglot import exp, parse_one
6389        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6390        'a.b.c'
6391
6392    Returns:
6393        The table name.
6394    """
6395
6396    table = maybe_parse(table, into=Table, dialect=dialect)
6397
6398    if not table:
6399        raise ValueError(f"Cannot parse {table}")
6400
6401    return ".".join(
6402        part.sql(dialect=dialect, identify=True)
6403        if not SAFE_IDENTIFIER_RE.match(part.name)
6404        else part.name
6405        for part in table.parts
6406    )

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.
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 replace_tables(expression: ~E, mapping: Dict[str, str], copy: bool = True) -> ~E:
6409def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E:
6410    """Replace all tables in expression according to the mapping.
6411
6412    Args:
6413        expression: expression node to be transformed and replaced.
6414        mapping: mapping of table names.
6415        copy: whether or not to copy the expression.
6416
6417    Examples:
6418        >>> from sqlglot import exp, parse_one
6419        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6420        'SELECT * FROM c'
6421
6422    Returns:
6423        The mapped expression.
6424    """
6425
6426    def _replace_tables(node: Expression) -> Expression:
6427        if isinstance(node, Table):
6428            new_name = mapping.get(table_name(node))
6429            if new_name:
6430                return to_table(
6431                    new_name,
6432                    **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")},
6433                )
6434        return node
6435
6436    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.
  • 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:
6439def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6440    """Replace placeholders in an expression.
6441
6442    Args:
6443        expression: expression node to be transformed and replaced.
6444        args: positional names that will substitute unnamed placeholders in the given order.
6445        kwargs: keyword arguments that will substitute named placeholders.
6446
6447    Examples:
6448        >>> from sqlglot import exp, parse_one
6449        >>> replace_placeholders(
6450        ...     parse_one("select * from :tbl where ? = ?"),
6451        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6452        ... ).sql()
6453        "SELECT * FROM foo WHERE str_col = 'b'"
6454
6455    Returns:
6456        The mapped expression.
6457    """
6458
6459    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6460        if isinstance(node, Placeholder):
6461            if node.name:
6462                new_name = kwargs.get(node.name)
6463                if new_name:
6464                    return convert(new_name)
6465            else:
6466                try:
6467                    return convert(next(args))
6468                except StopIteration:
6469                    pass
6470        return node
6471
6472    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], copy: bool = True) -> Expression:
6475def expand(
6476    expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True
6477) -> Expression:
6478    """Transforms an expression by expanding all referenced sources into subqueries.
6479
6480    Examples:
6481        >>> from sqlglot import parse_one
6482        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6483        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6484
6485        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6486        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6487
6488    Args:
6489        expression: The expression to expand.
6490        sources: A dictionary of name to Subqueryables.
6491        copy: Whether or not to copy the expression during transformation. Defaults to True.
6492
6493    Returns:
6494        The transformed expression.
6495    """
6496
6497    def _expand(node: Expression):
6498        if isinstance(node, Table):
6499            name = table_name(node)
6500            source = sources.get(name)
6501            if source:
6502                subquery = source.subquery(node.alias or name)
6503                subquery.comments = [f"source: {name}"]
6504                return subquery.transform(_expand, copy=False)
6505        return node
6506
6507    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.
  • 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:
6510def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6511    """
6512    Returns a Func expression.
6513
6514    Examples:
6515        >>> func("abs", 5).sql()
6516        'ABS(5)'
6517
6518        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6519        'CAST(5 AS DOUBLE)'
6520
6521    Args:
6522        name: the name of the function to build.
6523        args: the args used to instantiate the function of interest.
6524        dialect: the source dialect.
6525        kwargs: the kwargs used to instantiate the function of interest.
6526
6527    Note:
6528        The arguments `args` and `kwargs` are mutually exclusive.
6529
6530    Returns:
6531        An instance of the function of interest, or an anonymous function, if `name` doesn't
6532        correspond to an existing `sqlglot.expressions.Func` class.
6533    """
6534    if args and kwargs:
6535        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6536
6537    from sqlglot.dialects.dialect import Dialect
6538
6539    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6540    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6541
6542    parser = Dialect.get_or_raise(dialect)().parser()
6543    from_args_list = parser.FUNCTIONS.get(name.upper())
6544
6545    if from_args_list:
6546        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6547    else:
6548        kwargs = kwargs or {"expressions": converted}
6549        function = Anonymous(this=name, **kwargs)
6550
6551    for error_message in function.error_messages(converted):
6552        raise ValueError(error_message)
6553
6554    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:
6557def case(
6558    expression: t.Optional[ExpOrStr] = None,
6559    **opts,
6560) -> Case:
6561    """
6562    Initialize a CASE statement.
6563
6564    Example:
6565        case().when("a = 1", "foo").else_("bar")
6566
6567    Args:
6568        expression: Optionally, the input expression (not all dialects support this)
6569        **opts: Extra keyword arguments for parsing `expression`
6570    """
6571    if expression is not None:
6572        this = maybe_parse(expression, **opts)
6573    else:
6574        this = None
6575    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:
6578def true() -> Boolean:
6579    """
6580    Returns a true Boolean expression.
6581    """
6582    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6585def false() -> Boolean:
6586    """
6587    Returns a false Boolean expression.
6588    """
6589    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6592def null() -> Null:
6593    """
6594    Returns a Null expression.
6595    """
6596    return Null()

Returns a Null expression.

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