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

Converts the column into a dot expression.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3433    def unwrap(self) -> Subquery:
3434        expression = self
3435        while expression.same_parent and expression.is_wrapper:
3436            expression = t.cast(Subquery, expression.parent)
3437        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):
3459class TableSample(Expression):
3460    arg_types = {
3461        "this": False,
3462        "expressions": False,
3463        "method": False,
3464        "bucket_numerator": False,
3465        "bucket_denominator": False,
3466        "bucket_field": False,
3467        "percent": False,
3468        "rows": False,
3469        "size": False,
3470        "seed": False,
3471        "kind": False,
3472    }
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):
3475class Tag(Expression):
3476    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3477
3478    arg_types = {
3479        "this": False,
3480        "prefix": False,
3481        "postfix": False,
3482    }

Tags are used for generating arbitrary sql like SELECT x.

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

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

key = 'kwarg'
class Like(Binary, Predicate):
3984class Like(Binary, Predicate):
3985    pass
key = 'like'
class LikeAny(Binary, Predicate):
3988class LikeAny(Binary, Predicate):
3989    pass
key = 'likeany'
class LT(Binary, Predicate):
3992class LT(Binary, Predicate):
3993    pass
key = 'lt'
class LTE(Binary, Predicate):
3996class LTE(Binary, Predicate):
3997    pass
key = 'lte'
class Mod(Binary):
4000class Mod(Binary):
4001    pass
key = 'mod'
class Mul(Binary):
4004class Mul(Binary):
4005    pass
key = 'mul'
class NEQ(Binary, Predicate):
4008class NEQ(Binary, Predicate):
4009    pass
key = 'neq'
class SimilarTo(Binary, Predicate):
4012class SimilarTo(Binary, Predicate):
4013    pass
key = 'similarto'
class Slice(Binary):
4016class Slice(Binary):
4017    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4020class Sub(Binary):
4021    pass
key = 'sub'
class ArrayOverlaps(Binary):
4024class ArrayOverlaps(Binary):
4025    pass
key = 'arrayoverlaps'
class Unary(Condition):
4030class Unary(Condition):
4031    pass
key = 'unary'
class BitwiseNot(Unary):
4034class BitwiseNot(Unary):
4035    pass
key = 'bitwisenot'
class Not(Unary):
4038class Not(Unary):
4039    pass
key = 'not'
class Paren(Unary):
4042class Paren(Unary):
4043    arg_types = {"this": True, "with": False}
4044
4045    @property
4046    def output_name(self) -> str:
4047        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):
4050class Neg(Unary):
4051    pass
key = 'neg'
class Alias(Expression):
4054class Alias(Expression):
4055    arg_types = {"this": True, "alias": False}
4056
4057    @property
4058    def output_name(self) -> str:
4059        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):
4062class Aliases(Expression):
4063    arg_types = {"this": True, "expressions": True}
4064
4065    @property
4066    def aliases(self):
4067        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
4070class AtTimeZone(Expression):
4071    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4074class Between(Predicate):
4075    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4078class Bracket(Condition):
4079    arg_types = {"this": True, "expressions": True}
4080
4081    @property
4082    def output_name(self) -> str:
4083        if len(self.expressions) == 1:
4084            return self.expressions[0].output_name
4085
4086        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):
4089class SafeBracket(Bracket):
4090    """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):
4093class Distinct(Expression):
4094    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4097class In(Predicate):
4098    arg_types = {
4099        "this": True,
4100        "expressions": False,
4101        "query": False,
4102        "unnest": False,
4103        "field": False,
4104        "is_global": False,
4105    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4109class ForIn(Expression):
4110    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4113class TimeUnit(Expression):
4114    """Automatically converts unit arg into a var."""
4115
4116    arg_types = {"unit": False}
4117
4118    UNABBREVIATED_UNIT_NAME = {
4119        "d": "day",
4120        "h": "hour",
4121        "m": "minute",
4122        "ms": "millisecond",
4123        "ns": "nanosecond",
4124        "q": "quarter",
4125        "s": "second",
4126        "us": "microsecond",
4127        "w": "week",
4128        "y": "year",
4129    }
4130
4131    VAR_LIKE = (Column, Literal, Var)
4132
4133    def __init__(self, **args):
4134        unit = args.get("unit")
4135        if isinstance(unit, self.VAR_LIKE):
4136            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4137        elif isinstance(unit, Week):
4138            unit.set("this", Var(this=unit.this.name))
4139
4140        super().__init__(**args)
4141
4142    @property
4143    def unit(self) -> t.Optional[Var]:
4144        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4133    def __init__(self, **args):
4134        unit = args.get("unit")
4135        if isinstance(unit, self.VAR_LIKE):
4136            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4137        elif isinstance(unit, Week):
4138            unit.set("this", Var(this=unit.this.name))
4139
4140        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):
4147class IntervalOp(TimeUnit):
4148    arg_types = {"unit": True, "expression": True}
4149
4150    def interval(self):
4151        return Interval(
4152            this=self.expression.copy(),
4153            unit=self.unit.copy(),
4154        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4150    def interval(self):
4151        return Interval(
4152            this=self.expression.copy(),
4153            unit=self.unit.copy(),
4154        )
key = 'intervalop'
class IntervalSpan(DataType):
4160class IntervalSpan(DataType):
4161    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4164class Interval(TimeUnit):
4165    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4168class IgnoreNulls(Expression):
4169    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4172class RespectNulls(Expression):
4173    pass
key = 'respectnulls'
class Func(Condition):
4177class Func(Condition):
4178    """
4179    The base class for all function expressions.
4180
4181    Attributes:
4182        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4183            treated as a variable length argument and the argument's value will be stored as a list.
4184        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4185            for this function expression. These values are used to map this node to a name during parsing
4186            as well as to provide the function's name during SQL string generation. By default the SQL
4187            name is set to the expression's class name transformed to snake case.
4188    """
4189
4190    is_var_len_args = False
4191
4192    @classmethod
4193    def from_arg_list(cls, args):
4194        if cls.is_var_len_args:
4195            all_arg_keys = list(cls.arg_types)
4196            # If this function supports variable length argument treat the last argument as such.
4197            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4198            num_non_var = len(non_var_len_arg_keys)
4199
4200            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4201            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4202        else:
4203            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4204
4205        return cls(**args_dict)
4206
4207    @classmethod
4208    def sql_names(cls):
4209        if cls is Func:
4210            raise NotImplementedError(
4211                "SQL name is only supported by concrete function implementations"
4212            )
4213        if "_sql_names" not in cls.__dict__:
4214            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4215        return cls._sql_names
4216
4217    @classmethod
4218    def sql_name(cls):
4219        return cls.sql_names()[0]
4220
4221    @classmethod
4222    def default_parser_mappings(cls):
4223        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):
4192    @classmethod
4193    def from_arg_list(cls, args):
4194        if cls.is_var_len_args:
4195            all_arg_keys = list(cls.arg_types)
4196            # If this function supports variable length argument treat the last argument as such.
4197            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4198            num_non_var = len(non_var_len_arg_keys)
4199
4200            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4201            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4202        else:
4203            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4204
4205        return cls(**args_dict)
@classmethod
def sql_names(cls):
4207    @classmethod
4208    def sql_names(cls):
4209        if cls is Func:
4210            raise NotImplementedError(
4211                "SQL name is only supported by concrete function implementations"
4212            )
4213        if "_sql_names" not in cls.__dict__:
4214            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4215        return cls._sql_names
@classmethod
def sql_name(cls):
4217    @classmethod
4218    def sql_name(cls):
4219        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4221    @classmethod
4222    def default_parser_mappings(cls):
4223        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4226class AggFunc(Func):
4227    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4230class ParameterizedAgg(AggFunc):
4231    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4234class Abs(Func):
4235    pass
key = 'abs'
class ArgMax(AggFunc):
4238class ArgMax(AggFunc):
4239    arg_types = {"this": True, "expression": True, "count": False}
4240    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4243class ArgMin(AggFunc):
4244    arg_types = {"this": True, "expression": True, "count": False}
4245    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4248class ApproxTopK(AggFunc):
4249    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4252class Flatten(Func):
4253    pass
key = 'flatten'
class Transform(Func):
4257class Transform(Func):
4258    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4261class Anonymous(Func):
4262    arg_types = {"this": True, "expressions": False}
4263    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4268class Hll(AggFunc):
4269    arg_types = {"this": True, "expressions": False}
4270    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4273class ApproxDistinct(AggFunc):
4274    arg_types = {"this": True, "accuracy": False}
4275    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4278class Array(Func):
4279    arg_types = {"expressions": False}
4280    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4284class ToChar(Func):
4285    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tochar'
class GenerateSeries(Func):
4288class GenerateSeries(Func):
4289    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4292class ArrayAgg(AggFunc):
4293    pass
key = 'arrayagg'
class ArrayAll(Func):
4296class ArrayAll(Func):
4297    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4300class ArrayAny(Func):
4301    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4304class ArrayConcat(Func):
4305    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4306    arg_types = {"this": True, "expressions": False}
4307    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4310class ArrayContains(Binary, Func):
4311    pass
key = 'arraycontains'
class ArrayContained(Binary):
4314class ArrayContained(Binary):
4315    pass
key = 'arraycontained'
class ArrayFilter(Func):
4318class ArrayFilter(Func):
4319    arg_types = {"this": True, "expression": True}
4320    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4323class ArrayJoin(Func):
4324    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4327class ArraySize(Func):
4328    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4331class ArraySort(Func):
4332    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4335class ArraySum(Func):
4336    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4339class ArrayUnionAgg(AggFunc):
4340    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4343class Avg(AggFunc):
4344    pass
key = 'avg'
class AnyValue(AggFunc):
4347class AnyValue(AggFunc):
4348    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):
4351class First(Func):
4352    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4355class Last(Func):
4356    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4359class Case(Func):
4360    arg_types = {"this": False, "ifs": True, "default": False}
4361
4362    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4363        instance = maybe_copy(self, copy)
4364        instance.append(
4365            "ifs",
4366            If(
4367                this=maybe_parse(condition, copy=copy, **opts),
4368                true=maybe_parse(then, copy=copy, **opts),
4369            ),
4370        )
4371        return instance
4372
4373    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4374        instance = maybe_copy(self, copy)
4375        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4376        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:
4362    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4363        instance = maybe_copy(self, copy)
4364        instance.append(
4365            "ifs",
4366            If(
4367                this=maybe_parse(condition, copy=copy, **opts),
4368                true=maybe_parse(then, copy=copy, **opts),
4369            ),
4370        )
4371        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4373    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4374        instance = maybe_copy(self, copy)
4375        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4376        return instance
key = 'case'
class Cast(Func):
4379class Cast(Func):
4380    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4381
4382    @property
4383    def name(self) -> str:
4384        return self.this.name
4385
4386    @property
4387    def to(self) -> DataType:
4388        return self.args["to"]
4389
4390    @property
4391    def output_name(self) -> str:
4392        return self.name
4393
4394    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4395        """
4396        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4397        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4398        array<int> != array<float>.
4399
4400        Args:
4401            dtypes: the data types to compare this Cast's DataType to.
4402
4403        Returns:
4404            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4405        """
4406        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:
4394    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4395        """
4396        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4397        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4398        array<int> != array<float>.
4399
4400        Args:
4401            dtypes: the data types to compare this Cast's DataType to.
4402
4403        Returns:
4404            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4405        """
4406        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):
4409class TryCast(Cast):
4410    pass
key = 'trycast'
class CastToStrType(Func):
4413class CastToStrType(Func):
4414    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4417class Collate(Binary, Func):
4418    pass
key = 'collate'
class Ceil(Func):
4421class Ceil(Func):
4422    arg_types = {"this": True, "decimals": False}
4423    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4426class Coalesce(Func):
4427    arg_types = {"this": True, "expressions": False}
4428    is_var_len_args = True
4429    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4432class Chr(Func):
4433    arg_types = {"this": True, "charset": False, "expressions": False}
4434    is_var_len_args = True
4435    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4438class Concat(Func):
4439    arg_types = {"expressions": True}
4440    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4443class SafeConcat(Concat):
4444    pass
key = 'safeconcat'
class ConcatWs(Concat):
4447class ConcatWs(Concat):
4448    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4451class Count(AggFunc):
4452    arg_types = {"this": False, "expressions": False}
4453    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4456class CountIf(AggFunc):
4457    pass
key = 'countif'
class CurrentDate(Func):
4460class CurrentDate(Func):
4461    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4464class CurrentDatetime(Func):
4465    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4468class CurrentTime(Func):
4469    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4472class CurrentTimestamp(Func):
4473    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4476class CurrentUser(Func):
4477    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4480class DateAdd(Func, IntervalOp):
4481    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4484class DateSub(Func, IntervalOp):
4485    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4488class DateDiff(Func, TimeUnit):
4489    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4490    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4493class DateTrunc(Func):
4494    arg_types = {"unit": True, "this": True, "zone": False}
4495
4496    @property
4497    def unit(self) -> Expression:
4498        return self.args["unit"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4501class DatetimeAdd(Func, IntervalOp):
4502    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4505class DatetimeSub(Func, IntervalOp):
4506    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4509class DatetimeDiff(Func, TimeUnit):
4510    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4513class DatetimeTrunc(Func, TimeUnit):
4514    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4517class DayOfWeek(Func):
4518    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4521class DayOfMonth(Func):
4522    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4525class DayOfYear(Func):
4526    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4529class ToDays(Func):
4530    pass
key = 'todays'
class WeekOfYear(Func):
4533class WeekOfYear(Func):
4534    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4537class MonthsBetween(Func):
4538    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4541class LastDateOfMonth(Func):
4542    pass
key = 'lastdateofmonth'
class Extract(Func):
4545class Extract(Func):
4546    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4549class Timestamp(Func):
4550    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4553class TimestampAdd(Func, TimeUnit):
4554    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4557class TimestampSub(Func, TimeUnit):
4558    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4561class TimestampDiff(Func, TimeUnit):
4562    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4565class TimestampTrunc(Func, TimeUnit):
4566    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4569class TimeAdd(Func, TimeUnit):
4570    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4573class TimeSub(Func, TimeUnit):
4574    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4577class TimeDiff(Func, TimeUnit):
4578    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4581class TimeTrunc(Func, TimeUnit):
4582    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4585class DateFromParts(Func):
4586    _sql_names = ["DATEFROMPARTS"]
4587    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4590class DateStrToDate(Func):
4591    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4594class DateToDateStr(Func):
4595    pass
key = 'datetodatestr'
class DateToDi(Func):
4598class DateToDi(Func):
4599    pass
key = 'datetodi'
class Date(Func):
4603class Date(Func):
4604    arg_types = {"this": False, "zone": False, "expressions": False}
4605    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4608class Day(Func):
4609    pass
key = 'day'
class Decode(Func):
4612class Decode(Func):
4613    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4616class DiToDate(Func):
4617    pass
key = 'ditodate'
class Encode(Func):
4620class Encode(Func):
4621    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4624class Exp(Func):
4625    pass
key = 'exp'
class Explode(Func):
4629class Explode(Func):
4630    arg_types = {"this": True, "expressions": False}
4631    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4634class ExplodeOuter(Explode):
4635    pass
key = 'explodeouter'
class Posexplode(Explode):
4638class Posexplode(Explode):
4639    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4642class PosexplodeOuter(Posexplode):
4643    pass
key = 'posexplodeouter'
class Floor(Func):
4646class Floor(Func):
4647    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4650class FromBase64(Func):
4651    pass
key = 'frombase64'
class ToBase64(Func):
4654class ToBase64(Func):
4655    pass
key = 'tobase64'
class Greatest(Func):
4658class Greatest(Func):
4659    arg_types = {"this": True, "expressions": False}
4660    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4663class GroupConcat(AggFunc):
4664    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4667class Hex(Func):
4668    pass
key = 'hex'
class Xor(Connector, Func):
4671class Xor(Connector, Func):
4672    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4675class If(Func):
4676    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4679class Nullif(Func):
4680    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4683class Initcap(Func):
4684    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4687class IsNan(Func):
4688    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class FormatJson(Expression):
4691class FormatJson(Expression):
4692    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4695class JSONKeyValue(Expression):
4696    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4699class JSONObject(Func):
4700    arg_types = {
4701        "expressions": False,
4702        "null_handling": False,
4703        "unique_keys": False,
4704        "return_type": False,
4705        "encoding": False,
4706    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4710class JSONArray(Func):
4711    arg_types = {
4712        "expressions": True,
4713        "null_handling": False,
4714        "return_type": False,
4715        "strict": False,
4716    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4720class JSONArrayAgg(Func):
4721    arg_types = {
4722        "this": True,
4723        "order": False,
4724        "null_handling": False,
4725        "return_type": False,
4726        "strict": False,
4727    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4732class JSONColumnDef(Expression):
4733    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):
4736class JSONSchema(Expression):
4737    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4741class JSONTable(Func):
4742    arg_types = {
4743        "this": True,
4744        "schema": True,
4745        "path": False,
4746        "error_handling": False,
4747        "empty_handling": False,
4748    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4751class OpenJSONColumnDef(Expression):
4752    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):
4755class OpenJSON(Func):
4756    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4759class JSONBContains(Binary):
4760    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4763class JSONExtract(Binary, Func):
4764    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4767class JSONExtractScalar(JSONExtract):
4768    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4771class JSONBExtract(JSONExtract):
4772    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4775class JSONBExtractScalar(JSONExtract):
4776    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4779class JSONFormat(Func):
4780    arg_types = {"this": False, "options": False}
4781    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4785class JSONArrayContains(Binary, Predicate, Func):
4786    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4789class ParseJSON(Func):
4790    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4791    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4792    arg_types = {"this": True, "expressions": False}
4793    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
4796class Least(Func):
4797    arg_types = {"this": True, "expressions": False}
4798    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4801class Left(Func):
4802    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4809class Length(Func):
4810    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4813class Levenshtein(Func):
4814    arg_types = {
4815        "this": True,
4816        "expression": False,
4817        "ins_cost": False,
4818        "del_cost": False,
4819        "sub_cost": False,
4820    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4823class Ln(Func):
4824    pass
key = 'ln'
class Log(Func):
4827class Log(Func):
4828    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4831class Log2(Func):
4832    pass
key = 'log2'
class Log10(Func):
4835class Log10(Func):
4836    pass
key = 'log10'
class LogicalOr(AggFunc):
4839class LogicalOr(AggFunc):
4840    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4843class LogicalAnd(AggFunc):
4844    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4847class Lower(Func):
4848    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4851class Map(Func):
4852    arg_types = {"keys": False, "values": False}
4853
4854    @property
4855    def keys(self) -> t.List[Expression]:
4856        keys = self.args.get("keys")
4857        return keys.expressions if keys else []
4858
4859    @property
4860    def values(self) -> t.List[Expression]:
4861        values = self.args.get("values")
4862        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
values: List[Expression]
key = 'map'
class MapFromEntries(Func):
4865class MapFromEntries(Func):
4866    pass
key = 'mapfromentries'
class StarMap(Func):
4869class StarMap(Func):
4870    pass
key = 'starmap'
class VarMap(Func):
4873class VarMap(Func):
4874    arg_types = {"keys": True, "values": True}
4875    is_var_len_args = True
4876
4877    @property
4878    def keys(self) -> t.List[Expression]:
4879        return self.args["keys"].expressions
4880
4881    @property
4882    def values(self) -> t.List[Expression]:
4883        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):
4887class MatchAgainst(Func):
4888    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4891class Max(AggFunc):
4892    arg_types = {"this": True, "expressions": False}
4893    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4896class MD5(Func):
4897    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4901class MD5Digest(Func):
4902    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4905class Min(AggFunc):
4906    arg_types = {"this": True, "expressions": False}
4907    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4910class Month(Func):
4911    pass
key = 'month'
class Nvl2(Func):
4914class Nvl2(Func):
4915    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
4919class Predict(Func):
4920    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
4923class Pow(Binary, Func):
4924    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4927class PercentileCont(AggFunc):
4928    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4931class PercentileDisc(AggFunc):
4932    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4935class Quantile(AggFunc):
4936    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4939class ApproxQuantile(Quantile):
4940    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):
4943class RangeN(Func):
4944    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4947class ReadCSV(Func):
4948    _sql_names = ["READ_CSV"]
4949    is_var_len_args = True
4950    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4953class Reduce(Func):
4954    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):
4957class RegexpExtract(Func):
4958    arg_types = {
4959        "this": True,
4960        "expression": True,
4961        "position": False,
4962        "occurrence": False,
4963        "parameters": False,
4964        "group": False,
4965    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
4968class RegexpReplace(Func):
4969    arg_types = {
4970        "this": True,
4971        "expression": True,
4972        "replacement": True,
4973        "position": False,
4974        "occurrence": False,
4975        "parameters": False,
4976        "modifiers": False,
4977    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
4980class RegexpLike(Binary, Func):
4981    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
4984class RegexpILike(Binary, Func):
4985    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
4990class RegexpSplit(Func):
4991    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
4994class Repeat(Func):
4995    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
4998class Round(Func):
4999    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5002class RowNumber(Func):
5003    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5006class SafeDivide(Func):
5007    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SetAgg(AggFunc):
5010class SetAgg(AggFunc):
5011    pass
key = 'setagg'
class SHA(Func):
5014class SHA(Func):
5015    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5018class SHA2(Func):
5019    _sql_names = ["SHA2"]
5020    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5023class SortArray(Func):
5024    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5027class Split(Func):
5028    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5033class Substring(Func):
5034    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5037class StandardHash(Func):
5038    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5041class StartsWith(Func):
5042    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5043    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5046class StrPosition(Func):
5047    arg_types = {
5048        "this": True,
5049        "substr": True,
5050        "position": False,
5051        "instance": False,
5052    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5055class StrToDate(Func):
5056    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5059class StrToTime(Func):
5060    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5065class StrToUnix(Func):
5066    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5071class StrToMap(Func):
5072    arg_types = {
5073        "this": True,
5074        "pair_delim": False,
5075        "key_value_delim": False,
5076        "duplicate_resolution_callback": False,
5077    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5080class NumberToStr(Func):
5081    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5084class FromBase(Func):
5085    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5088class Struct(Func):
5089    arg_types = {"expressions": False}
5090    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5093class StructExtract(Func):
5094    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5099class Stuff(Func):
5100    _sql_names = ["STUFF", "INSERT"]
5101    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):
5104class Sum(AggFunc):
5105    pass
key = 'sum'
class Sqrt(Func):
5108class Sqrt(Func):
5109    pass
key = 'sqrt'
class Stddev(AggFunc):
5112class Stddev(AggFunc):
5113    pass
key = 'stddev'
class StddevPop(AggFunc):
5116class StddevPop(AggFunc):
5117    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5120class StddevSamp(AggFunc):
5121    pass
key = 'stddevsamp'
class TimeToStr(Func):
5124class TimeToStr(Func):
5125    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5128class TimeToTimeStr(Func):
5129    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5132class TimeToUnix(Func):
5133    pass
key = 'timetounix'
class TimeStrToDate(Func):
5136class TimeStrToDate(Func):
5137    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5140class TimeStrToTime(Func):
5141    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5144class TimeStrToUnix(Func):
5145    pass
key = 'timestrtounix'
class Trim(Func):
5148class Trim(Func):
5149    arg_types = {
5150        "this": True,
5151        "expression": False,
5152        "position": False,
5153        "collation": False,
5154    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5157class TsOrDsAdd(Func, TimeUnit):
5158    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsadd'
class TsOrDsToDateStr(Func):
5161class TsOrDsToDateStr(Func):
5162    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5165class TsOrDsToDate(Func):
5166    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
5169class TsOrDiToDi(Func):
5170    pass
key = 'tsorditodi'
class Unhex(Func):
5173class Unhex(Func):
5174    pass
key = 'unhex'
class UnixToStr(Func):
5177class UnixToStr(Func):
5178    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5183class UnixToTime(Func):
5184    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5185
5186    SECONDS = Literal.string("seconds")
5187    MILLIS = Literal.string("millis")
5188    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):
5191class UnixToTimeStr(Func):
5192    pass
key = 'unixtotimestr'
class Upper(Func):
5195class Upper(Func):
5196    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5199class Variance(AggFunc):
5200    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5203class VariancePop(AggFunc):
5204    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5207class Week(Func):
5208    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5211class XMLTable(Func):
5212    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):
5215class Year(Func):
5216    pass
key = 'year'
class Use(Expression):
5219class Use(Expression):
5220    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5223class Merge(Expression):
5224    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):
5227class When(Func):
5228    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):
5233class NextValueFor(Func):
5234    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:
5271def maybe_parse(
5272    sql_or_expression: ExpOrStr,
5273    *,
5274    into: t.Optional[IntoType] = None,
5275    dialect: DialectType = None,
5276    prefix: t.Optional[str] = None,
5277    copy: bool = False,
5278    **opts,
5279) -> Expression:
5280    """Gracefully handle a possible string or expression.
5281
5282    Example:
5283        >>> maybe_parse("1")
5284        (LITERAL this: 1, is_string: False)
5285        >>> maybe_parse(to_identifier("x"))
5286        (IDENTIFIER this: x, quoted: False)
5287
5288    Args:
5289        sql_or_expression: the SQL code string or an expression
5290        into: the SQLGlot Expression to parse into
5291        dialect: the dialect used to parse the input expressions (in the case that an
5292            input expression is a SQL string).
5293        prefix: a string to prefix the sql with before it gets parsed
5294            (automatically includes a space)
5295        copy: whether or not to copy the expression.
5296        **opts: other options to use to parse the input expressions (again, in the case
5297            that an input expression is a SQL string).
5298
5299    Returns:
5300        Expression: the parsed or given expression.
5301    """
5302    if isinstance(sql_or_expression, Expression):
5303        if copy:
5304            return sql_or_expression.copy()
5305        return sql_or_expression
5306
5307    if sql_or_expression is None:
5308        raise ParseError(f"SQL cannot be None")
5309
5310    import sqlglot
5311
5312    sql = str(sql_or_expression)
5313    if prefix:
5314        sql = f"{prefix} {sql}"
5315
5316    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):
5329def maybe_copy(instance, copy=True):
5330    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:
5511def union(
5512    left: ExpOrStr,
5513    right: ExpOrStr,
5514    distinct: bool = True,
5515    dialect: DialectType = None,
5516    copy: bool = True,
5517    **opts,
5518) -> Union:
5519    """
5520    Initializes a syntax tree from one UNION expression.
5521
5522    Example:
5523        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5524        'SELECT * FROM foo UNION SELECT * FROM bla'
5525
5526    Args:
5527        left: the SQL code string corresponding to the left-hand side.
5528            If an `Expression` instance is passed, it will be used as-is.
5529        right: the SQL code string corresponding to the right-hand side.
5530            If an `Expression` instance is passed, it will be used as-is.
5531        distinct: set the DISTINCT flag if and only if this is true.
5532        dialect: the dialect used to parse the input expression.
5533        copy: whether or not to copy the expression.
5534        opts: other options to use to parse the input expressions.
5535
5536    Returns:
5537        The new Union instance.
5538    """
5539    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5540    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5541
5542    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:
5545def intersect(
5546    left: ExpOrStr,
5547    right: ExpOrStr,
5548    distinct: bool = True,
5549    dialect: DialectType = None,
5550    copy: bool = True,
5551    **opts,
5552) -> Intersect:
5553    """
5554    Initializes a syntax tree from one INTERSECT expression.
5555
5556    Example:
5557        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5558        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5559
5560    Args:
5561        left: the SQL code string corresponding to the left-hand side.
5562            If an `Expression` instance is passed, it will be used as-is.
5563        right: the SQL code string corresponding to the right-hand side.
5564            If an `Expression` instance is passed, it will be used as-is.
5565        distinct: set the DISTINCT flag if and only if this is true.
5566        dialect: the dialect used to parse the input expression.
5567        copy: whether or not to copy the expression.
5568        opts: other options to use to parse the input expressions.
5569
5570    Returns:
5571        The new Intersect instance.
5572    """
5573    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5574    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5575
5576    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:
5579def except_(
5580    left: ExpOrStr,
5581    right: ExpOrStr,
5582    distinct: bool = True,
5583    dialect: DialectType = None,
5584    copy: bool = True,
5585    **opts,
5586) -> Except:
5587    """
5588    Initializes a syntax tree from one EXCEPT expression.
5589
5590    Example:
5591        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5592        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5593
5594    Args:
5595        left: the SQL code string corresponding to the left-hand side.
5596            If an `Expression` instance is passed, it will be used as-is.
5597        right: the SQL code string corresponding to the right-hand side.
5598            If an `Expression` instance is passed, it will be used as-is.
5599        distinct: set the DISTINCT flag if and only if this is true.
5600        dialect: the dialect used to parse the input expression.
5601        copy: whether or not to copy the expression.
5602        opts: other options to use to parse the input expressions.
5603
5604    Returns:
5605        The new Except instance.
5606    """
5607    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5608    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5609
5610    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:
5613def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5614    """
5615    Initializes a syntax tree from one or multiple SELECT expressions.
5616
5617    Example:
5618        >>> select("col1", "col2").from_("tbl").sql()
5619        'SELECT col1, col2 FROM tbl'
5620
5621    Args:
5622        *expressions: the SQL code string to parse as the expressions of a
5623            SELECT statement. If an Expression instance is passed, this is used as-is.
5624        dialect: the dialect used to parse the input expressions (in the case that an
5625            input expression is a SQL string).
5626        **opts: other options to use to parse the input expressions (again, in the case
5627            that an input expression is a SQL string).
5628
5629    Returns:
5630        Select: the syntax tree for the SELECT statement.
5631    """
5632    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:
5635def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5636    """
5637    Initializes a syntax tree from a FROM expression.
5638
5639    Example:
5640        >>> from_("tbl").select("col1", "col2").sql()
5641        'SELECT col1, col2 FROM tbl'
5642
5643    Args:
5644        *expression: the SQL code string to parse as the FROM expressions of a
5645            SELECT statement. If an Expression instance is passed, this is used as-is.
5646        dialect: the dialect used to parse the input expression (in the case that the
5647            input expression is a SQL string).
5648        **opts: other options to use to parse the input expressions (again, in the case
5649            that the input expression is a SQL string).
5650
5651    Returns:
5652        Select: the syntax tree for the SELECT statement.
5653    """
5654    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:
5657def update(
5658    table: str | Table,
5659    properties: dict,
5660    where: t.Optional[ExpOrStr] = None,
5661    from_: t.Optional[ExpOrStr] = None,
5662    dialect: DialectType = None,
5663    **opts,
5664) -> Update:
5665    """
5666    Creates an update statement.
5667
5668    Example:
5669        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5670        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5671
5672    Args:
5673        *properties: dictionary of properties to set which are
5674            auto converted to sql objects eg None -> NULL
5675        where: sql conditional parsed into a WHERE statement
5676        from_: sql statement parsed into a FROM statement
5677        dialect: the dialect used to parse the input expressions.
5678        **opts: other options to use to parse the input expressions.
5679
5680    Returns:
5681        Update: the syntax tree for the UPDATE statement.
5682    """
5683    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5684    update_expr.set(
5685        "expressions",
5686        [
5687            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5688            for k, v in properties.items()
5689        ],
5690    )
5691    if from_:
5692        update_expr.set(
5693            "from",
5694            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5695        )
5696    if isinstance(where, Condition):
5697        where = Where(this=where)
5698    if where:
5699        update_expr.set(
5700            "where",
5701            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5702        )
5703    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:
5706def delete(
5707    table: ExpOrStr,
5708    where: t.Optional[ExpOrStr] = None,
5709    returning: t.Optional[ExpOrStr] = None,
5710    dialect: DialectType = None,
5711    **opts,
5712) -> Delete:
5713    """
5714    Builds a delete statement.
5715
5716    Example:
5717        >>> delete("my_table", where="id > 1").sql()
5718        'DELETE FROM my_table WHERE id > 1'
5719
5720    Args:
5721        where: sql conditional parsed into a WHERE statement
5722        returning: sql conditional parsed into a RETURNING statement
5723        dialect: the dialect used to parse the input expressions.
5724        **opts: other options to use to parse the input expressions.
5725
5726    Returns:
5727        Delete: the syntax tree for the DELETE statement.
5728    """
5729    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5730    if where:
5731        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5732    if returning:
5733        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5734    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:
5737def insert(
5738    expression: ExpOrStr,
5739    into: ExpOrStr,
5740    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5741    overwrite: t.Optional[bool] = None,
5742    dialect: DialectType = None,
5743    copy: bool = True,
5744    **opts,
5745) -> Insert:
5746    """
5747    Builds an INSERT statement.
5748
5749    Example:
5750        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5751        'INSERT INTO tbl VALUES (1, 2, 3)'
5752
5753    Args:
5754        expression: the sql string or expression of the INSERT statement
5755        into: the tbl to insert data to.
5756        columns: optionally the table's column names.
5757        overwrite: whether to INSERT OVERWRITE or not.
5758        dialect: the dialect used to parse the input expressions.
5759        copy: whether or not to copy the expression.
5760        **opts: other options to use to parse the input expressions.
5761
5762    Returns:
5763        Insert: the syntax tree for the INSERT statement.
5764    """
5765    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5766    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5767
5768    if columns:
5769        this = _apply_list_builder(
5770            *columns,
5771            instance=Schema(this=this),
5772            arg="expressions",
5773            into=Identifier,
5774            copy=False,
5775            dialect=dialect,
5776            **opts,
5777        )
5778
5779    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:
5782def condition(
5783    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5784) -> Condition:
5785    """
5786    Initialize a logical condition expression.
5787
5788    Example:
5789        >>> condition("x=1").sql()
5790        'x = 1'
5791
5792        This is helpful for composing larger logical syntax trees:
5793        >>> where = condition("x=1")
5794        >>> where = where.and_("y=1")
5795        >>> Select().from_("tbl").select("*").where(where).sql()
5796        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5797
5798    Args:
5799        *expression: the SQL code string to parse.
5800            If an Expression instance is passed, this is used as-is.
5801        dialect: the dialect used to parse the input expression (in the case that the
5802            input expression is a SQL string).
5803        copy: Whether or not to copy `expression` (only applies to expressions).
5804        **opts: other options to use to parse the input expressions (again, in the case
5805            that the input expression is a SQL string).
5806
5807    Returns:
5808        The new Condition instance
5809    """
5810    return maybe_parse(
5811        expression,
5812        into=Condition,
5813        dialect=dialect,
5814        copy=copy,
5815        **opts,
5816    )

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

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

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

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

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

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

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

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

Returns a true Boolean expression.

def false() -> Boolean:
6580def false() -> Boolean:
6581    """
6582    Returns a false Boolean expression.
6583    """
6584    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6587def null() -> Null:
6588    """
6589    Returns a Null expression.
6590    """
6591    return Null()

Returns a Null expression.

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