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

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

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):
3792class PseudoType(DataType):
3793    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3797class ObjectIdentifier(DataType):
3798    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3802class SubqueryPredicate(Predicate):
3803    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3806class All(SubqueryPredicate):
3807    pass
key = 'all'
class Any(SubqueryPredicate):
3810class Any(SubqueryPredicate):
3811    pass
key = 'any'
class Exists(SubqueryPredicate):
3814class Exists(SubqueryPredicate):
3815    pass
key = 'exists'
class Command(Expression):
3820class Command(Expression):
3821    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3824class Transaction(Expression):
3825    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3828class Commit(Expression):
3829    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3832class Rollback(Expression):
3833    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3836class AlterTable(Expression):
3837    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):
3840class AddConstraint(Expression):
3841    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3844class DropPartition(Expression):
3845    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
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
arg_types = {'this': True, 'expression': True}
left: Expression
right: Expression
key = 'binary'
class Add(Binary):
3861class Add(Binary):
3862    pass
key = 'add'
class Connector(Binary):
3865class Connector(Binary):
3866    pass
key = 'connector'
class And(Connector):
3869class And(Connector):
3870    pass
key = 'and'
class Or(Connector):
3873class Or(Connector):
3874    pass
key = 'or'
class BitwiseAnd(Binary):
3877class BitwiseAnd(Binary):
3878    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3881class BitwiseLeftShift(Binary):
3882    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3885class BitwiseOr(Binary):
3886    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3889class BitwiseRightShift(Binary):
3890    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3893class BitwiseXor(Binary):
3894    pass
key = 'bitwisexor'
class Div(Binary):
3897class Div(Binary):
3898    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):
3901class Overlaps(Binary):
3902    pass
key = 'overlaps'
class Dot(Binary):
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))
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:
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))

Build a Dot object with a sequence of expressions.

key = 'dot'
class DPipe(Binary):
3923class DPipe(Binary):
3924    pass
key = 'dpipe'
class SafeDPipe(DPipe):
3927class SafeDPipe(DPipe):
3928    pass
key = 'safedpipe'
class EQ(Binary, Predicate):
3931class EQ(Binary, Predicate):
3932    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3935class NullSafeEQ(Binary, Predicate):
3936    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3939class NullSafeNEQ(Binary, Predicate):
3940    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3944class PropertyEQ(Binary):
3945    pass
key = 'propertyeq'
class Distance(Binary):
3948class Distance(Binary):
3949    pass
key = 'distance'
class Escape(Binary):
3952class Escape(Binary):
3953    pass
key = 'escape'
class Glob(Binary, Predicate):
3956class Glob(Binary, Predicate):
3957    pass
key = 'glob'
class GT(Binary, Predicate):
3960class GT(Binary, Predicate):
3961    pass
key = 'gt'
class GTE(Binary, Predicate):
3964class GTE(Binary, Predicate):
3965    pass
key = 'gte'
class ILike(Binary, Predicate):
3968class ILike(Binary, Predicate):
3969    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3972class ILikeAny(Binary, Predicate):
3973    pass
key = 'ilikeany'
class IntDiv(Binary):
3976class IntDiv(Binary):
3977    pass
key = 'intdiv'
class Is(Binary, Predicate):
3980class Is(Binary, Predicate):
3981    pass
key = 'is'
class Kwarg(Binary):
3984class Kwarg(Binary):
3985    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
3988class Like(Binary, Predicate):
3989    pass
key = 'like'
class LikeAny(Binary, Predicate):
3992class LikeAny(Binary, Predicate):
3993    pass
key = 'likeany'
class LT(Binary, Predicate):
3996class LT(Binary, Predicate):
3997    pass
key = 'lt'
class LTE(Binary, Predicate):
4000class LTE(Binary, Predicate):
4001    pass
key = 'lte'
class Mod(Binary):
4004class Mod(Binary):
4005    pass
key = 'mod'
class Mul(Binary):
4008class Mul(Binary):
4009    pass
key = 'mul'
class NEQ(Binary, Predicate):
4012class NEQ(Binary, Predicate):
4013    pass
key = 'neq'
class SimilarTo(Binary, Predicate):
4016class SimilarTo(Binary, Predicate):
4017    pass
key = 'similarto'
class Slice(Binary):
4020class Slice(Binary):
4021    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4024class Sub(Binary):
4025    pass
key = 'sub'
class ArrayOverlaps(Binary):
4028class ArrayOverlaps(Binary):
4029    pass
key = 'arrayoverlaps'
class Unary(Condition):
4034class Unary(Condition):
4035    pass
key = 'unary'
class BitwiseNot(Unary):
4038class BitwiseNot(Unary):
4039    pass
key = 'bitwisenot'
class Not(Unary):
4042class Not(Unary):
4043    pass
key = 'not'
class Paren(Unary):
4046class Paren(Unary):
4047    arg_types = {"this": True, "with": False}
4048
4049    @property
4050    def output_name(self) -> str:
4051        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):
4054class Neg(Unary):
4055    pass
key = 'neg'
class Alias(Expression):
4058class Alias(Expression):
4059    arg_types = {"this": True, "alias": False}
4060
4061    @property
4062    def output_name(self) -> str:
4063        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):
4066class Aliases(Expression):
4067    arg_types = {"this": True, "expressions": True}
4068
4069    @property
4070    def aliases(self):
4071        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
4074class AtTimeZone(Expression):
4075    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4078class Between(Predicate):
4079    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
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
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):
4093class SafeBracket(Bracket):
4094    """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):
4097class Distinct(Expression):
4098    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
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    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4113class ForIn(Expression):
4114    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
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")

Automatically converts unit arg into a var.

TimeUnit(**args)
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)
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):
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        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4154    def interval(self):
4155        return Interval(
4156            this=self.expression.copy(),
4157            unit=self.unit.copy(),
4158        )
key = 'intervalop'
class IntervalSpan(DataType):
4164class IntervalSpan(DataType):
4165    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4168class Interval(TimeUnit):
4169    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4172class IgnoreNulls(Expression):
4173    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4176class RespectNulls(Expression):
4177    pass
key = 'respectnulls'
class Func(Condition):
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()}

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):
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)
@classmethod
def sql_names(cls):
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
@classmethod
def sql_name(cls):
4221    @classmethod
4222    def sql_name(cls):
4223        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4225    @classmethod
4226    def default_parser_mappings(cls):
4227        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4230class AggFunc(Func):
4231    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4234class ParameterizedAgg(AggFunc):
4235    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4238class Abs(Func):
4239    pass
key = 'abs'
class ArgMax(AggFunc):
4242class ArgMax(AggFunc):
4243    arg_types = {"this": True, "expression": True, "count": False}
4244    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4247class ArgMin(AggFunc):
4248    arg_types = {"this": True, "expression": True, "count": False}
4249    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4252class ApproxTopK(AggFunc):
4253    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4256class Flatten(Func):
4257    pass
key = 'flatten'
class Transform(Func):
4261class Transform(Func):
4262    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4265class Anonymous(Func):
4266    arg_types = {"this": True, "expressions": False}
4267    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4272class Hll(AggFunc):
4273    arg_types = {"this": True, "expressions": False}
4274    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4277class ApproxDistinct(AggFunc):
4278    arg_types = {"this": True, "accuracy": False}
4279    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4282class Array(Func):
4283    arg_types = {"expressions": False}
4284    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4288class ToChar(Func):
4289    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tochar'
class GenerateSeries(Func):
4292class GenerateSeries(Func):
4293    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4296class ArrayAgg(AggFunc):
4297    pass
key = 'arrayagg'
class ArrayAll(Func):
4300class ArrayAll(Func):
4301    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4304class ArrayAny(Func):
4305    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4308class ArrayConcat(Func):
4309    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4310    arg_types = {"this": True, "expressions": False}
4311    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4314class ArrayContains(Binary, Func):
4315    pass
key = 'arraycontains'
class ArrayContained(Binary):
4318class ArrayContained(Binary):
4319    pass
key = 'arraycontained'
class ArrayFilter(Func):
4322class ArrayFilter(Func):
4323    arg_types = {"this": True, "expression": True}
4324    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4327class ArrayJoin(Func):
4328    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4331class ArraySize(Func):
4332    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4335class ArraySort(Func):
4336    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4339class ArraySum(Func):
4340    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4343class ArrayUnionAgg(AggFunc):
4344    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4347class Avg(AggFunc):
4348    pass
key = 'avg'
class AnyValue(AggFunc):
4351class AnyValue(AggFunc):
4352    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):
4355class First(Func):
4356    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4359class Last(Func):
4360    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
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
arg_types = {'this': False, 'ifs': True, 'default': False}
def when( self, condition: Union[str, Expression], then: Union[str, Expression], copy: bool = True, **opts) -> Case:
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
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
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
key = 'case'
class Cast(Func):
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)
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:
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)

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):
4413class TryCast(Cast):
4414    pass
key = 'trycast'
class CastToStrType(Func):
4417class CastToStrType(Func):
4418    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4421class Collate(Binary, Func):
4422    pass
key = 'collate'
class Ceil(Func):
4425class Ceil(Func):
4426    arg_types = {"this": True, "decimals": False}
4427    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4430class Coalesce(Func):
4431    arg_types = {"this": True, "expressions": False}
4432    is_var_len_args = True
4433    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4436class Chr(Func):
4437    arg_types = {"this": True, "charset": False, "expressions": False}
4438    is_var_len_args = True
4439    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4442class Concat(Func):
4443    arg_types = {"expressions": True}
4444    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4447class SafeConcat(Concat):
4448    pass
key = 'safeconcat'
class ConcatWs(Concat):
4451class ConcatWs(Concat):
4452    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4455class Count(AggFunc):
4456    arg_types = {"this": False, "expressions": False}
4457    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4460class CountIf(AggFunc):
4461    pass
key = 'countif'
class CurrentDate(Func):
4464class CurrentDate(Func):
4465    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4468class CurrentDatetime(Func):
4469    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4472class CurrentTime(Func):
4473    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4476class CurrentTimestamp(Func):
4477    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4480class CurrentUser(Func):
4481    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4484class DateAdd(Func, IntervalOp):
4485    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4488class DateSub(Func, IntervalOp):
4489    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4492class DateDiff(Func, TimeUnit):
4493    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4494    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
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"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4505class DatetimeAdd(Func, IntervalOp):
4506    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4509class DatetimeSub(Func, IntervalOp):
4510    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4513class DatetimeDiff(Func, TimeUnit):
4514    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4517class DatetimeTrunc(Func, TimeUnit):
4518    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4521class DayOfWeek(Func):
4522    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4525class DayOfMonth(Func):
4526    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4529class DayOfYear(Func):
4530    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4533class ToDays(Func):
4534    pass
key = 'todays'
class WeekOfYear(Func):
4537class WeekOfYear(Func):
4538    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4541class MonthsBetween(Func):
4542    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4545class LastDateOfMonth(Func):
4546    pass
key = 'lastdateofmonth'
class Extract(Func):
4549class Extract(Func):
4550    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4553class Timestamp(Func):
4554    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4557class TimestampAdd(Func, TimeUnit):
4558    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4561class TimestampSub(Func, TimeUnit):
4562    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4565class TimestampDiff(Func, TimeUnit):
4566    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4569class TimestampTrunc(Func, TimeUnit):
4570    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4573class TimeAdd(Func, TimeUnit):
4574    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4577class TimeSub(Func, TimeUnit):
4578    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4581class TimeDiff(Func, TimeUnit):
4582    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4585class TimeTrunc(Func, TimeUnit):
4586    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4589class DateFromParts(Func):
4590    _sql_names = ["DATEFROMPARTS"]
4591    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4594class DateStrToDate(Func):
4595    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4598class DateToDateStr(Func):
4599    pass
key = 'datetodatestr'
class DateToDi(Func):
4602class DateToDi(Func):
4603    pass
key = 'datetodi'
class Date(Func):
4607class Date(Func):
4608    arg_types = {"this": False, "zone": False, "expressions": False}
4609    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4612class Day(Func):
4613    pass
key = 'day'
class Decode(Func):
4616class Decode(Func):
4617    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4620class DiToDate(Func):
4621    pass
key = 'ditodate'
class Encode(Func):
4624class Encode(Func):
4625    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4628class Exp(Func):
4629    pass
key = 'exp'
class Explode(Func):
4633class Explode(Func):
4634    arg_types = {"this": True, "expressions": False}
4635    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4638class ExplodeOuter(Explode):
4639    pass
key = 'explodeouter'
class Posexplode(Explode):
4642class Posexplode(Explode):
4643    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4646class PosexplodeOuter(Posexplode):
4647    pass
key = 'posexplodeouter'
class Floor(Func):
4650class Floor(Func):
4651    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4654class FromBase64(Func):
4655    pass
key = 'frombase64'
class ToBase64(Func):
4658class ToBase64(Func):
4659    pass
key = 'tobase64'
class Greatest(Func):
4662class Greatest(Func):
4663    arg_types = {"this": True, "expressions": False}
4664    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4667class GroupConcat(AggFunc):
4668    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4671class Hex(Func):
4672    pass
key = 'hex'
class Xor(Connector, Func):
4675class Xor(Connector, Func):
4676    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4679class If(Func):
4680    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4683class Nullif(Func):
4684    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4687class Initcap(Func):
4688    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4691class IsNan(Func):
4692    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class FormatJson(Expression):
4695class FormatJson(Expression):
4696    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4699class JSONKeyValue(Expression):
4700    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
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    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4714class JSONArray(Func):
4715    arg_types = {
4716        "expressions": True,
4717        "null_handling": False,
4718        "return_type": False,
4719        "strict": False,
4720    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4724class JSONArrayAgg(Func):
4725    arg_types = {
4726        "this": True,
4727        "order": False,
4728        "null_handling": False,
4729        "return_type": False,
4730        "strict": False,
4731    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4736class JSONColumnDef(Expression):
4737    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):
4740class JSONSchema(Expression):
4741    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4745class JSONTable(Func):
4746    arg_types = {
4747        "this": True,
4748        "schema": True,
4749        "path": False,
4750        "error_handling": False,
4751        "empty_handling": False,
4752    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4755class OpenJSONColumnDef(Expression):
4756    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):
4759class OpenJSON(Func):
4760    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4763class JSONBContains(Binary):
4764    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4767class JSONExtract(Binary, Func):
4768    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4771class JSONExtractScalar(JSONExtract):
4772    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4775class JSONBExtract(JSONExtract):
4776    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4779class JSONBExtractScalar(JSONExtract):
4780    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4783class JSONFormat(Func):
4784    arg_types = {"this": False, "options": False}
4785    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4789class JSONArrayContains(Binary, Predicate, Func):
4790    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
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
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
4800class Least(Func):
4801    arg_types = {"this": True, "expressions": False}
4802    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4805class Left(Func):
4806    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4813class Length(Func):
4814    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
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    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4827class Ln(Func):
4828    pass
key = 'ln'
class Log(Func):
4831class Log(Func):
4832    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4835class Log2(Func):
4836    pass
key = 'log2'
class Log10(Func):
4839class Log10(Func):
4840    pass
key = 'log10'
class LogicalOr(AggFunc):
4843class LogicalOr(AggFunc):
4844    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4847class LogicalAnd(AggFunc):
4848    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4851class Lower(Func):
4852    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
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 []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
values: List[Expression]
key = 'map'
class MapFromEntries(Func):
4869class MapFromEntries(Func):
4870    pass
key = 'mapfromentries'
class StarMap(Func):
4873class StarMap(Func):
4874    pass
key = 'starmap'
class VarMap(Func):
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
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
values: List[Expression]
key = 'varmap'
class MatchAgainst(Func):
4891class MatchAgainst(Func):
4892    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4895class Max(AggFunc):
4896    arg_types = {"this": True, "expressions": False}
4897    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4900class MD5(Func):
4901    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4905class MD5Digest(Func):
4906    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4909class Min(AggFunc):
4910    arg_types = {"this": True, "expressions": False}
4911    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4914class Month(Func):
4915    pass
key = 'month'
class Nvl2(Func):
4918class Nvl2(Func):
4919    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
4923class Predict(Func):
4924    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
4927class Pow(Binary, Func):
4928    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4931class PercentileCont(AggFunc):
4932    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4935class PercentileDisc(AggFunc):
4936    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4939class Quantile(AggFunc):
4940    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4943class ApproxQuantile(Quantile):
4944    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):
4947class RangeN(Func):
4948    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4951class ReadCSV(Func):
4952    _sql_names = ["READ_CSV"]
4953    is_var_len_args = True
4954    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4957class Reduce(Func):
4958    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):
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    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
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    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
4984class RegexpLike(Binary, Func):
4985    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
4988class RegexpILike(Binary, Func):
4989    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
4994class RegexpSplit(Func):
4995    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
4998class Repeat(Func):
4999    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5002class Round(Func):
5003    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5006class RowNumber(Func):
5007    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5010class SafeDivide(Func):
5011    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SetAgg(AggFunc):
5014class SetAgg(AggFunc):
5015    pass
key = 'setagg'
class SHA(Func):
5018class SHA(Func):
5019    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5022class SHA2(Func):
5023    _sql_names = ["SHA2"]
5024    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5027class SortArray(Func):
5028    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5031class Split(Func):
5032    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5037class Substring(Func):
5038    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5041class StandardHash(Func):
5042    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5045class StartsWith(Func):
5046    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5047    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5050class StrPosition(Func):
5051    arg_types = {
5052        "this": True,
5053        "substr": True,
5054        "position": False,
5055        "instance": False,
5056    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5059class StrToDate(Func):
5060    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5063class StrToTime(Func):
5064    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5069class StrToUnix(Func):
5070    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5075class StrToMap(Func):
5076    arg_types = {
5077        "this": True,
5078        "pair_delim": False,
5079        "key_value_delim": False,
5080        "duplicate_resolution_callback": False,
5081    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5084class NumberToStr(Func):
5085    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5088class FromBase(Func):
5089    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5092class Struct(Func):
5093    arg_types = {"expressions": False}
5094    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5097class StructExtract(Func):
5098    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5103class Stuff(Func):
5104    _sql_names = ["STUFF", "INSERT"]
5105    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):
5108class Sum(AggFunc):
5109    pass
key = 'sum'
class Sqrt(Func):
5112class Sqrt(Func):
5113    pass
key = 'sqrt'
class Stddev(AggFunc):
5116class Stddev(AggFunc):
5117    pass
key = 'stddev'
class StddevPop(AggFunc):
5120class StddevPop(AggFunc):
5121    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5124class StddevSamp(AggFunc):
5125    pass
key = 'stddevsamp'
class TimeToStr(Func):
5128class TimeToStr(Func):
5129    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5132class TimeToTimeStr(Func):
5133    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5136class TimeToUnix(Func):
5137    pass
key = 'timetounix'
class TimeStrToDate(Func):
5140class TimeStrToDate(Func):
5141    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5144class TimeStrToTime(Func):
5145    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5148class TimeStrToUnix(Func):
5149    pass
key = 'timestrtounix'
class Trim(Func):
5152class Trim(Func):
5153    arg_types = {
5154        "this": True,
5155        "expression": False,
5156        "position": False,
5157        "collation": False,
5158    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5161class TsOrDsAdd(Func, TimeUnit):
5162    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsadd'
class TsOrDsToDateStr(Func):
5165class TsOrDsToDateStr(Func):
5166    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5169class TsOrDsToDate(Func):
5170    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
5173class TsOrDiToDi(Func):
5174    pass
key = 'tsorditodi'
class Unhex(Func):
5177class Unhex(Func):
5178    pass
key = 'unhex'
class UnixToStr(Func):
5181class UnixToStr(Func):
5182    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
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")
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):
5195class UnixToTimeStr(Func):
5196    pass
key = 'unixtotimestr'
class Upper(Func):
5199class Upper(Func):
5200    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5203class Variance(AggFunc):
5204    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5207class VariancePop(AggFunc):
5208    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5211class Week(Func):
5212    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5215class XMLTable(Func):
5216    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):
5219class Year(Func):
5220    pass
key = 'year'
class Use(Expression):
5223class Use(Expression):
5224    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5227class Merge(Expression):
5228    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):
5231class When(Func):
5232    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):
5237class NextValueFor(Func):
5238    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:
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)

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):
5333def maybe_copy(instance, copy=True):
5334    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:
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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Replace children of an expression with the result of a lambda fun(child) -> exp.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
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    }

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

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

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

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

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

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:
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=[])

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:
6577def true() -> Boolean:
6578    """
6579    Returns a true Boolean expression.
6580    """
6581    return Boolean(this=True)

Returns a true Boolean expression.

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

Returns a false Boolean expression.

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

Returns a Null expression.

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