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

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1086class Create(DDL):
1087    arg_types = {
1088        "with": False,
1089        "this": True,
1090        "kind": True,
1091        "expression": False,
1092        "exists": False,
1093        "properties": False,
1094        "replace": False,
1095        "unique": False,
1096        "indexes": False,
1097        "no_schema_binding": False,
1098        "begin": False,
1099        "end": False,
1100        "clone": False,
1101    }
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):
1107class Clone(Expression):
1108    arg_types = {
1109        "this": True,
1110        "when": False,
1111        "kind": False,
1112        "shallow": False,
1113        "expression": False,
1114        "copy": False,
1115    }
arg_types = {'this': True, 'when': False, 'kind': False, 'shallow': False, 'expression': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1118class Describe(Expression):
1119    arg_types = {"this": True, "kind": False, "expressions": False}
arg_types = {'this': True, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1122class Kill(Expression):
1123    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1126class Pragma(Expression):
1127    pass
key = 'pragma'
class Set(Expression):
1130class Set(Expression):
1131    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class SetItem(Expression):
1134class SetItem(Expression):
1135    arg_types = {
1136        "this": False,
1137        "expressions": False,
1138        "kind": False,
1139        "collate": False,  # MySQL SET NAMES statement
1140        "global": False,
1141    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1144class Show(Expression):
1145    arg_types = {
1146        "this": True,
1147        "target": False,
1148        "offset": False,
1149        "limit": False,
1150        "like": False,
1151        "where": False,
1152        "db": False,
1153        "scope": False,
1154        "scope_kind": False,
1155        "full": False,
1156        "mutex": False,
1157        "query": False,
1158        "channel": False,
1159        "global": False,
1160        "log": False,
1161        "position": False,
1162        "types": False,
1163    }
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):
1166class UserDefinedFunction(Expression):
1167    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1170class CharacterSet(Expression):
1171    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1174class With(Expression):
1175    arg_types = {"expressions": True, "recursive": False}
1176
1177    @property
1178    def recursive(self) -> bool:
1179        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
key = 'with'
class WithinGroup(Expression):
1182class WithinGroup(Expression):
1183    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1188class CTE(DerivedTable):
1189    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1192class TableAlias(Expression):
1193    arg_types = {"this": False, "columns": False}
1194
1195    @property
1196    def columns(self):
1197        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
key = 'tablealias'
class BitString(Condition):
1200class BitString(Condition):
1201    pass
key = 'bitstring'
class HexString(Condition):
1204class HexString(Condition):
1205    pass
key = 'hexstring'
class ByteString(Condition):
1208class ByteString(Condition):
1209    pass
key = 'bytestring'
class RawString(Condition):
1212class RawString(Condition):
1213    pass
key = 'rawstring'
class Column(Condition):
1216class Column(Condition):
1217    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1218
1219    @property
1220    def table(self) -> str:
1221        return self.text("table")
1222
1223    @property
1224    def db(self) -> str:
1225        return self.text("db")
1226
1227    @property
1228    def catalog(self) -> str:
1229        return self.text("catalog")
1230
1231    @property
1232    def output_name(self) -> str:
1233        return self.name
1234
1235    @property
1236    def parts(self) -> t.List[Identifier]:
1237        """Return the parts of a column in order catalog, db, table, name."""
1238        return [
1239            t.cast(Identifier, self.args[part])
1240            for part in ("catalog", "db", "table", "this")
1241            if self.args.get(part)
1242        ]
1243
1244    def to_dot(self) -> Dot | Identifier:
1245        """Converts the column into a dot expression."""
1246        parts = self.parts
1247        parent = self.parent
1248
1249        while parent:
1250            if isinstance(parent, Dot):
1251                parts.append(parent.expression)
1252            parent = parent.parent
1253
1254        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
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:
1244    def to_dot(self) -> Dot | Identifier:
1245        """Converts the column into a dot expression."""
1246        parts = self.parts
1247        parent = self.parent
1248
1249        while parent:
1250            if isinstance(parent, Dot):
1251                parts.append(parent.expression)
1252            parent = parent.parent
1253
1254        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1257class ColumnPosition(Expression):
1258    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1261class ColumnDef(Expression):
1262    arg_types = {
1263        "this": True,
1264        "kind": False,
1265        "constraints": False,
1266        "exists": False,
1267        "position": False,
1268    }
1269
1270    @property
1271    def constraints(self) -> t.List[ColumnConstraint]:
1272        return self.args.get("constraints") or []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
key = 'columndef'
class AlterColumn(Expression):
1275class AlterColumn(Expression):
1276    arg_types = {
1277        "this": True,
1278        "dtype": False,
1279        "collate": False,
1280        "using": False,
1281        "default": False,
1282        "drop": False,
1283    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1286class RenameTable(Expression):
1287    pass
key = 'renametable'
class SwapTable(Expression):
1290class SwapTable(Expression):
1291    pass
key = 'swaptable'
class Comment(Expression):
1294class Comment(Expression):
1295    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):
1298class Comprehension(Expression):
1299    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):
1303class MergeTreeTTLAction(Expression):
1304    arg_types = {
1305        "this": True,
1306        "delete": False,
1307        "recompress": False,
1308        "to_disk": False,
1309        "to_volume": False,
1310    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1314class MergeTreeTTL(Expression):
1315    arg_types = {
1316        "expressions": True,
1317        "where": False,
1318        "group": False,
1319        "aggregates": False,
1320    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1324class IndexConstraintOption(Expression):
1325    arg_types = {
1326        "key_block_size": False,
1327        "using": False,
1328        "parser": False,
1329        "comment": False,
1330        "visible": False,
1331        "engine_attr": False,
1332        "secondary_engine_attr": False,
1333    }
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):
1336class ColumnConstraint(Expression):
1337    arg_types = {"this": False, "kind": True}
1338
1339    @property
1340    def kind(self) -> ColumnConstraintKind:
1341        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1344class ColumnConstraintKind(Expression):
1345    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1348class AutoIncrementColumnConstraint(ColumnConstraintKind):
1349    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1352class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1353    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1356class CaseSpecificColumnConstraint(ColumnConstraintKind):
1357    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1360class CharacterSetColumnConstraint(ColumnConstraintKind):
1361    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1364class CheckColumnConstraint(ColumnConstraintKind):
1365    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1368class ClusteredColumnConstraint(ColumnConstraintKind):
1369    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1372class CollateColumnConstraint(ColumnConstraintKind):
1373    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1376class CommentColumnConstraint(ColumnConstraintKind):
1377    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1380class CompressColumnConstraint(ColumnConstraintKind):
1381    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1384class DateFormatColumnConstraint(ColumnConstraintKind):
1385    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1388class DefaultColumnConstraint(ColumnConstraintKind):
1389    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1392class EncodeColumnConstraint(ColumnConstraintKind):
1393    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1396class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1397    # this: True -> ALWAYS, this: False -> BY DEFAULT
1398    arg_types = {
1399        "this": False,
1400        "expression": False,
1401        "on_null": False,
1402        "start": False,
1403        "increment": False,
1404        "minvalue": False,
1405        "maxvalue": False,
1406        "cycle": False,
1407    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1410class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1411    arg_types = {"start": True, "hidden": False}
arg_types = {'start': True, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1415class IndexColumnConstraint(ColumnConstraintKind):
1416    arg_types = {
1417        "this": False,
1418        "schema": True,
1419        "kind": False,
1420        "index_type": False,
1421        "options": False,
1422    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1425class InlineLengthColumnConstraint(ColumnConstraintKind):
1426    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1429class NonClusteredColumnConstraint(ColumnConstraintKind):
1430    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1433class NotForReplicationColumnConstraint(ColumnConstraintKind):
1434    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1437class NotNullColumnConstraint(ColumnConstraintKind):
1438    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1442class OnUpdateColumnConstraint(ColumnConstraintKind):
1443    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1446class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1447    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1450class TitleColumnConstraint(ColumnConstraintKind):
1451    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1454class UniqueColumnConstraint(ColumnConstraintKind):
1455    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1458class UppercaseColumnConstraint(ColumnConstraintKind):
1459    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1462class PathColumnConstraint(ColumnConstraintKind):
1463    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1468class ComputedColumnConstraint(ColumnConstraintKind):
1469    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1472class Constraint(Expression):
1473    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1476class Delete(DML):
1477    arg_types = {
1478        "with": False,
1479        "this": False,
1480        "using": False,
1481        "where": False,
1482        "returning": False,
1483        "limit": False,
1484        "tables": False,  # Multiple-Table Syntax (MySQL)
1485    }
1486
1487    def delete(
1488        self,
1489        table: ExpOrStr,
1490        dialect: DialectType = None,
1491        copy: bool = True,
1492        **opts,
1493    ) -> Delete:
1494        """
1495        Create a DELETE expression or replace the table on an existing DELETE expression.
1496
1497        Example:
1498            >>> delete("tbl").sql()
1499            'DELETE FROM tbl'
1500
1501        Args:
1502            table: the table from which to delete.
1503            dialect: the dialect used to parse the input expression.
1504            copy: if `False`, modify this expression instance in-place.
1505            opts: other options to use to parse the input expressions.
1506
1507        Returns:
1508            Delete: the modified expression.
1509        """
1510        return _apply_builder(
1511            expression=table,
1512            instance=self,
1513            arg="this",
1514            dialect=dialect,
1515            into=Table,
1516            copy=copy,
1517            **opts,
1518        )
1519
1520    def where(
1521        self,
1522        *expressions: t.Optional[ExpOrStr],
1523        append: bool = True,
1524        dialect: DialectType = None,
1525        copy: bool = True,
1526        **opts,
1527    ) -> Delete:
1528        """
1529        Append to or set the WHERE expressions.
1530
1531        Example:
1532            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1533            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1534
1535        Args:
1536            *expressions: the SQL code strings to parse.
1537                If an `Expression` instance is passed, it will be used as-is.
1538                Multiple expressions are combined with an AND operator.
1539            append: if `True`, AND the new expressions to any existing expression.
1540                Otherwise, this resets the expression.
1541            dialect: the dialect used to parse the input expressions.
1542            copy: if `False`, modify this expression instance in-place.
1543            opts: other options to use to parse the input expressions.
1544
1545        Returns:
1546            Delete: the modified expression.
1547        """
1548        return _apply_conjunction_builder(
1549            *expressions,
1550            instance=self,
1551            arg="where",
1552            append=append,
1553            into=Where,
1554            dialect=dialect,
1555            copy=copy,
1556            **opts,
1557        )
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:
1487    def delete(
1488        self,
1489        table: ExpOrStr,
1490        dialect: DialectType = None,
1491        copy: bool = True,
1492        **opts,
1493    ) -> Delete:
1494        """
1495        Create a DELETE expression or replace the table on an existing DELETE expression.
1496
1497        Example:
1498            >>> delete("tbl").sql()
1499            'DELETE FROM tbl'
1500
1501        Args:
1502            table: the table from which to delete.
1503            dialect: the dialect used to parse the input expression.
1504            copy: if `False`, modify this expression instance in-place.
1505            opts: other options to use to parse the input expressions.
1506
1507        Returns:
1508            Delete: the modified expression.
1509        """
1510        return _apply_builder(
1511            expression=table,
1512            instance=self,
1513            arg="this",
1514            dialect=dialect,
1515            into=Table,
1516            copy=copy,
1517            **opts,
1518        )

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

Append to or set the WHERE expressions.

Example:
>>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
"DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

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

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):
1729class OnConflict(Expression):
1730    arg_types = {
1731        "duplicate": False,
1732        "expressions": False,
1733        "nothing": False,
1734        "key": False,
1735        "constraint": False,
1736    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1739class Returning(Expression):
1740    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1744class Introducer(Expression):
1745    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1749class National(Expression):
1750    pass
key = 'national'
class LoadData(Expression):
1753class LoadData(Expression):
1754    arg_types = {
1755        "this": True,
1756        "local": False,
1757        "overwrite": False,
1758        "inpath": True,
1759        "partition": False,
1760        "input_format": False,
1761        "serde": False,
1762    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1765class Partition(Expression):
1766    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1769class Fetch(Expression):
1770    arg_types = {
1771        "direction": False,
1772        "count": False,
1773        "percent": False,
1774        "with_ties": False,
1775    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1778class Group(Expression):
1779    arg_types = {
1780        "expressions": False,
1781        "grouping_sets": False,
1782        "cube": False,
1783        "rollup": False,
1784        "totals": False,
1785        "all": False,
1786    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1789class Lambda(Expression):
1790    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1793class Limit(Expression):
1794    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1797class Literal(Condition):
1798    arg_types = {"this": True, "is_string": True}
1799
1800    @property
1801    def hashable_args(self) -> t.Any:
1802        return (self.this, self.args.get("is_string"))
1803
1804    @classmethod
1805    def number(cls, number) -> Literal:
1806        return cls(this=str(number), is_string=False)
1807
1808    @classmethod
1809    def string(cls, string) -> Literal:
1810        return cls(this=str(string), is_string=True)
1811
1812    @property
1813    def output_name(self) -> str:
1814        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
@classmethod
def number(cls, number) -> Literal:
1804    @classmethod
1805    def number(cls, number) -> Literal:
1806        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1808    @classmethod
1809    def string(cls, string) -> Literal:
1810        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):
1817class Join(Expression):
1818    arg_types = {
1819        "this": True,
1820        "on": False,
1821        "side": False,
1822        "kind": False,
1823        "using": False,
1824        "method": False,
1825        "global": False,
1826        "hint": False,
1827    }
1828
1829    @property
1830    def method(self) -> str:
1831        return self.text("method").upper()
1832
1833    @property
1834    def kind(self) -> str:
1835        return self.text("kind").upper()
1836
1837    @property
1838    def side(self) -> str:
1839        return self.text("side").upper()
1840
1841    @property
1842    def hint(self) -> str:
1843        return self.text("hint").upper()
1844
1845    @property
1846    def alias_or_name(self) -> str:
1847        return self.this.alias_or_name
1848
1849    def on(
1850        self,
1851        *expressions: t.Optional[ExpOrStr],
1852        append: bool = True,
1853        dialect: DialectType = None,
1854        copy: bool = True,
1855        **opts,
1856    ) -> Join:
1857        """
1858        Append to or set the ON expressions.
1859
1860        Example:
1861            >>> import sqlglot
1862            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1863            'JOIN x ON y = 1'
1864
1865        Args:
1866            *expressions: the SQL code strings to parse.
1867                If an `Expression` instance is passed, it will be used as-is.
1868                Multiple expressions are combined with an AND operator.
1869            append: if `True`, AND the new expressions to any existing expression.
1870                Otherwise, this resets the expression.
1871            dialect: the dialect used to parse the input expressions.
1872            copy: if `False`, modify this expression instance in-place.
1873            opts: other options to use to parse the input expressions.
1874
1875        Returns:
1876            The modified Join expression.
1877        """
1878        join = _apply_conjunction_builder(
1879            *expressions,
1880            instance=self,
1881            arg="on",
1882            append=append,
1883            dialect=dialect,
1884            copy=copy,
1885            **opts,
1886        )
1887
1888        if join.kind == "CROSS":
1889            join.set("kind", None)
1890
1891        return join
1892
1893    def using(
1894        self,
1895        *expressions: t.Optional[ExpOrStr],
1896        append: bool = True,
1897        dialect: DialectType = None,
1898        copy: bool = True,
1899        **opts,
1900    ) -> Join:
1901        """
1902        Append to or set the USING expressions.
1903
1904        Example:
1905            >>> import sqlglot
1906            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1907            'JOIN x USING (foo, bla)'
1908
1909        Args:
1910            *expressions: the SQL code strings to parse.
1911                If an `Expression` instance is passed, it will be used as-is.
1912            append: if `True`, concatenate the new expressions to the existing "using" list.
1913                Otherwise, this resets the expression.
1914            dialect: the dialect used to parse the input expressions.
1915            copy: if `False`, modify this expression instance in-place.
1916            opts: other options to use to parse the input expressions.
1917
1918        Returns:
1919            The modified Join expression.
1920        """
1921        join = _apply_list_builder(
1922            *expressions,
1923            instance=self,
1924            arg="using",
1925            append=append,
1926            dialect=dialect,
1927            copy=copy,
1928            **opts,
1929        )
1930
1931        if join.kind == "CROSS":
1932            join.set("kind", None)
1933
1934        return join
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:
1849    def on(
1850        self,
1851        *expressions: t.Optional[ExpOrStr],
1852        append: bool = True,
1853        dialect: DialectType = None,
1854        copy: bool = True,
1855        **opts,
1856    ) -> Join:
1857        """
1858        Append to or set the ON expressions.
1859
1860        Example:
1861            >>> import sqlglot
1862            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1863            'JOIN x ON y = 1'
1864
1865        Args:
1866            *expressions: the SQL code strings to parse.
1867                If an `Expression` instance is passed, it will be used as-is.
1868                Multiple expressions are combined with an AND operator.
1869            append: if `True`, AND the new expressions to any existing expression.
1870                Otherwise, this resets the expression.
1871            dialect: the dialect used to parse the input expressions.
1872            copy: if `False`, modify this expression instance in-place.
1873            opts: other options to use to parse the input expressions.
1874
1875        Returns:
1876            The modified Join expression.
1877        """
1878        join = _apply_conjunction_builder(
1879            *expressions,
1880            instance=self,
1881            arg="on",
1882            append=append,
1883            dialect=dialect,
1884            copy=copy,
1885            **opts,
1886        )
1887
1888        if join.kind == "CROSS":
1889            join.set("kind", None)
1890
1891        return join

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:
1893    def using(
1894        self,
1895        *expressions: t.Optional[ExpOrStr],
1896        append: bool = True,
1897        dialect: DialectType = None,
1898        copy: bool = True,
1899        **opts,
1900    ) -> Join:
1901        """
1902        Append to or set the USING expressions.
1903
1904        Example:
1905            >>> import sqlglot
1906            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1907            'JOIN x USING (foo, bla)'
1908
1909        Args:
1910            *expressions: the SQL code strings to parse.
1911                If an `Expression` instance is passed, it will be used as-is.
1912            append: if `True`, concatenate the new expressions to the existing "using" list.
1913                Otherwise, this resets the expression.
1914            dialect: the dialect used to parse the input expressions.
1915            copy: if `False`, modify this expression instance in-place.
1916            opts: other options to use to parse the input expressions.
1917
1918        Returns:
1919            The modified Join expression.
1920        """
1921        join = _apply_list_builder(
1922            *expressions,
1923            instance=self,
1924            arg="using",
1925            append=append,
1926            dialect=dialect,
1927            copy=copy,
1928            **opts,
1929        )
1930
1931        if join.kind == "CROSS":
1932            join.set("kind", None)
1933
1934        return join

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):
1937class Lateral(UDTF):
1938    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):
1941class MatchRecognize(Expression):
1942    arg_types = {
1943        "partition_by": False,
1944        "order": False,
1945        "measures": False,
1946        "rows": False,
1947        "after": False,
1948        "pattern": False,
1949        "define": False,
1950        "alias": False,
1951    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1956class Final(Expression):
1957    pass
key = 'final'
class Offset(Expression):
1960class Offset(Expression):
1961    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1964class Order(Expression):
1965    arg_types = {"this": False, "expressions": True}
arg_types = {'this': False, 'expressions': True}
key = 'order'
class Cluster(Order):
1970class Cluster(Order):
1971    pass
key = 'cluster'
class Distribute(Order):
1974class Distribute(Order):
1975    pass
key = 'distribute'
class Sort(Order):
1978class Sort(Order):
1979    pass
key = 'sort'
class Ordered(Expression):
1982class Ordered(Expression):
1983    arg_types = {"this": True, "desc": False, "nulls_first": True}
arg_types = {'this': True, 'desc': False, 'nulls_first': True}
key = 'ordered'
class Property(Expression):
1986class Property(Expression):
1987    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
1990class AlgorithmProperty(Property):
1991    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
1994class AutoIncrementProperty(Property):
1995    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class BlockCompressionProperty(Property):
1998class BlockCompressionProperty(Property):
1999    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):
2002class CharacterSetProperty(Property):
2003    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2006class ChecksumProperty(Property):
2007    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2010class CollateProperty(Property):
2011    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2014class CopyGrantsProperty(Property):
2015    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2018class DataBlocksizeProperty(Property):
2019    arg_types = {
2020        "size": False,
2021        "units": False,
2022        "minimum": False,
2023        "maximum": False,
2024        "default": False,
2025    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2028class DefinerProperty(Property):
2029    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2032class DistKeyProperty(Property):
2033    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2036class DistStyleProperty(Property):
2037    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2040class EngineProperty(Property):
2041    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2044class HeapProperty(Property):
2045    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2048class ToTableProperty(Property):
2049    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2052class ExecuteAsProperty(Property):
2053    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2056class ExternalProperty(Property):
2057    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2060class FallbackProperty(Property):
2061    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2064class FileFormatProperty(Property):
2065    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2068class FreespaceProperty(Property):
2069    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InputModelProperty(Property):
2072class InputModelProperty(Property):
2073    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2076class OutputModelProperty(Property):
2077    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2080class IsolatedLoadingProperty(Property):
2081    arg_types = {
2082        "no": True,
2083        "concurrent": True,
2084        "for_all": True,
2085        "for_insert": True,
2086        "for_none": True,
2087    }
arg_types = {'no': True, 'concurrent': True, 'for_all': True, 'for_insert': True, 'for_none': True}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2090class JournalProperty(Property):
2091    arg_types = {
2092        "no": False,
2093        "dual": False,
2094        "before": False,
2095        "local": False,
2096        "after": False,
2097    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2100class LanguageProperty(Property):
2101    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2105class ClusteredByProperty(Property):
2106    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2109class DictProperty(Property):
2110    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2113class DictSubProperty(Property):
2114    pass
key = 'dictsubproperty'
class DictRange(Property):
2117class DictRange(Property):
2118    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2123class OnCluster(Property):
2124    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2127class LikeProperty(Property):
2128    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2131class LocationProperty(Property):
2132    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2135class LockingProperty(Property):
2136    arg_types = {
2137        "this": False,
2138        "kind": True,
2139        "for_or_in": False,
2140        "lock_type": True,
2141        "override": False,
2142    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2145class LogProperty(Property):
2146    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2149class MaterializedProperty(Property):
2150    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2153class MergeBlockRatioProperty(Property):
2154    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):
2157class NoPrimaryIndexProperty(Property):
2158    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2161class OnProperty(Property):
2162    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2165class OnCommitProperty(Property):
2166    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2169class PartitionedByProperty(Property):
2170    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2174class PartitionBoundSpec(Expression):
2175    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2176    arg_types = {
2177        "this": False,
2178        "expression": False,
2179        "from_expressions": False,
2180        "to_expressions": False,
2181    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2184class PartitionedOfProperty(Property):
2185    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2186    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2189class RemoteWithConnectionModelProperty(Property):
2190    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2193class ReturnsProperty(Property):
2194    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2197class RowFormatProperty(Property):
2198    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2201class RowFormatDelimitedProperty(Property):
2202    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2203    arg_types = {
2204        "fields": False,
2205        "escaped": False,
2206        "collection_items": False,
2207        "map_keys": False,
2208        "lines": False,
2209        "null": False,
2210        "serde": False,
2211    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2214class RowFormatSerdeProperty(Property):
2215    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2219class QueryTransform(Expression):
2220    arg_types = {
2221        "expressions": True,
2222        "command_script": True,
2223        "schema": False,
2224        "row_format_before": False,
2225        "record_writer": False,
2226        "row_format_after": False,
2227        "record_reader": False,
2228    }
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):
2231class SampleProperty(Property):
2232    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2235class SchemaCommentProperty(Property):
2236    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2239class SerdeProperties(Property):
2240    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2243class SetProperty(Property):
2244    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SettingsProperty(Property):
2247class SettingsProperty(Property):
2248    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2251class SortKeyProperty(Property):
2252    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlSecurityProperty(Property):
2255class SqlSecurityProperty(Property):
2256    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2259class StabilityProperty(Property):
2260    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2263class TemporaryProperty(Property):
2264    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2267class TransformModelProperty(Property):
2268    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2271class TransientProperty(Property):
2272    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2275class VolatileProperty(Property):
2276    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2279class WithDataProperty(Property):
2280    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2283class WithJournalTableProperty(Property):
2284    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2287class WithSystemVersioningProperty(Property):
2288    # this -> history table name, expression -> data consistency check
2289    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2292class Properties(Expression):
2293    arg_types = {"expressions": True}
2294
2295    NAME_TO_PROPERTY = {
2296        "ALGORITHM": AlgorithmProperty,
2297        "AUTO_INCREMENT": AutoIncrementProperty,
2298        "CHARACTER SET": CharacterSetProperty,
2299        "CLUSTERED_BY": ClusteredByProperty,
2300        "COLLATE": CollateProperty,
2301        "COMMENT": SchemaCommentProperty,
2302        "DEFINER": DefinerProperty,
2303        "DISTKEY": DistKeyProperty,
2304        "DISTSTYLE": DistStyleProperty,
2305        "ENGINE": EngineProperty,
2306        "EXECUTE AS": ExecuteAsProperty,
2307        "FORMAT": FileFormatProperty,
2308        "LANGUAGE": LanguageProperty,
2309        "LOCATION": LocationProperty,
2310        "PARTITIONED_BY": PartitionedByProperty,
2311        "RETURNS": ReturnsProperty,
2312        "ROW_FORMAT": RowFormatProperty,
2313        "SORTKEY": SortKeyProperty,
2314    }
2315
2316    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2317
2318    # CREATE property locations
2319    # Form: schema specified
2320    #   create [POST_CREATE]
2321    #     table a [POST_NAME]
2322    #     (b int) [POST_SCHEMA]
2323    #     with ([POST_WITH])
2324    #     index (b) [POST_INDEX]
2325    #
2326    # Form: alias selection
2327    #   create [POST_CREATE]
2328    #     table a [POST_NAME]
2329    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2330    #     index (c) [POST_INDEX]
2331    class Location(AutoName):
2332        POST_CREATE = auto()
2333        POST_NAME = auto()
2334        POST_SCHEMA = auto()
2335        POST_WITH = auto()
2336        POST_ALIAS = auto()
2337        POST_EXPRESSION = auto()
2338        POST_INDEX = auto()
2339        UNSUPPORTED = auto()
2340
2341    @classmethod
2342    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2343        expressions = []
2344        for key, value in properties_dict.items():
2345            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2346            if property_cls:
2347                expressions.append(property_cls(this=convert(value)))
2348            else:
2349                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2350
2351        return cls(expressions=expressions)
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:
2341    @classmethod
2342    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2343        expressions = []
2344        for key, value in properties_dict.items():
2345            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2346            if property_cls:
2347                expressions.append(property_cls(this=convert(value)))
2348            else:
2349                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2350
2351        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2331    class Location(AutoName):
2332        POST_CREATE = auto()
2333        POST_NAME = auto()
2334        POST_SCHEMA = auto()
2335        POST_WITH = auto()
2336        POST_ALIAS = auto()
2337        POST_EXPRESSION = auto()
2338        POST_INDEX = auto()
2339        UNSUPPORTED = auto()

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):
2354class Qualify(Expression):
2355    pass
key = 'qualify'
class InputOutputFormat(Expression):
2358class InputOutputFormat(Expression):
2359    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2363class Return(Expression):
2364    pass
key = 'return'
class Reference(Expression):
2367class Reference(Expression):
2368    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2371class Tuple(Expression):
2372    arg_types = {"expressions": False}
2373
2374    def isin(
2375        self,
2376        *expressions: t.Any,
2377        query: t.Optional[ExpOrStr] = None,
2378        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2379        copy: bool = True,
2380        **opts,
2381    ) -> In:
2382        return In(
2383            this=maybe_copy(self, copy),
2384            expressions=[convert(e, copy=copy) for e in expressions],
2385            query=maybe_parse(query, copy=copy, **opts) if query else None,
2386            unnest=Unnest(
2387                expressions=[
2388                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2389                ]
2390            )
2391            if unnest
2392            else None,
2393        )
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:
2374    def isin(
2375        self,
2376        *expressions: t.Any,
2377        query: t.Optional[ExpOrStr] = None,
2378        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2379        copy: bool = True,
2380        **opts,
2381    ) -> In:
2382        return In(
2383            this=maybe_copy(self, copy),
2384            expressions=[convert(e, copy=copy) for e in expressions],
2385            query=maybe_parse(query, copy=copy, **opts) if query else None,
2386            unnest=Unnest(
2387                expressions=[
2388                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2389                ]
2390            )
2391            if unnest
2392            else None,
2393        )
key = 'tuple'
class Subqueryable(Unionable):
2396class Subqueryable(Unionable):
2397    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2398        """
2399        Convert this expression to an aliased expression that can be used as a Subquery.
2400
2401        Example:
2402            >>> subquery = Select().select("x").from_("tbl").subquery()
2403            >>> Select().select("x").from_(subquery).sql()
2404            'SELECT x FROM (SELECT x FROM tbl)'
2405
2406        Args:
2407            alias (str | Identifier): an optional alias for the subquery
2408            copy (bool): if `False`, modify this expression instance in-place.
2409
2410        Returns:
2411            Alias: the subquery
2412        """
2413        instance = maybe_copy(self, copy)
2414        if not isinstance(alias, Expression):
2415            alias = TableAlias(this=to_identifier(alias)) if alias else None
2416
2417        return Subquery(this=instance, alias=alias)
2418
2419    def limit(
2420        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2421    ) -> Select:
2422        raise NotImplementedError
2423
2424    @property
2425    def ctes(self):
2426        with_ = self.args.get("with")
2427        if not with_:
2428            return []
2429        return with_.expressions
2430
2431    @property
2432    def selects(self) -> t.List[Expression]:
2433        raise NotImplementedError("Subqueryable objects must implement `selects`")
2434
2435    @property
2436    def named_selects(self) -> t.List[str]:
2437        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2438
2439    def select(
2440        self,
2441        *expressions: t.Optional[ExpOrStr],
2442        append: bool = True,
2443        dialect: DialectType = None,
2444        copy: bool = True,
2445        **opts,
2446    ) -> Subqueryable:
2447        raise NotImplementedError("Subqueryable objects must implement `select`")
2448
2449    def with_(
2450        self,
2451        alias: ExpOrStr,
2452        as_: ExpOrStr,
2453        recursive: t.Optional[bool] = None,
2454        append: bool = True,
2455        dialect: DialectType = None,
2456        copy: bool = True,
2457        **opts,
2458    ) -> Subqueryable:
2459        """
2460        Append to or set the common table expressions.
2461
2462        Example:
2463            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2464            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2465
2466        Args:
2467            alias: the SQL code string to parse as the table name.
2468                If an `Expression` instance is passed, this is used as-is.
2469            as_: the SQL code string to parse as the table expression.
2470                If an `Expression` instance is passed, it will be used as-is.
2471            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2472            append: if `True`, add to any existing expressions.
2473                Otherwise, this resets the expressions.
2474            dialect: the dialect used to parse the input expression.
2475            copy: if `False`, modify this expression instance in-place.
2476            opts: other options to use to parse the input expressions.
2477
2478        Returns:
2479            The modified expression.
2480        """
2481        return _apply_cte_builder(
2482            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2483        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2397    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2398        """
2399        Convert this expression to an aliased expression that can be used as a Subquery.
2400
2401        Example:
2402            >>> subquery = Select().select("x").from_("tbl").subquery()
2403            >>> Select().select("x").from_(subquery).sql()
2404            'SELECT x FROM (SELECT x FROM tbl)'
2405
2406        Args:
2407            alias (str | Identifier): an optional alias for the subquery
2408            copy (bool): if `False`, modify this expression instance in-place.
2409
2410        Returns:
2411            Alias: the subquery
2412        """
2413        instance = maybe_copy(self, copy)
2414        if not isinstance(alias, Expression):
2415            alias = TableAlias(this=to_identifier(alias)) if alias else None
2416
2417        return Subquery(this=instance, alias=alias)

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:
2419    def limit(
2420        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2421    ) -> Select:
2422        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:
2439    def select(
2440        self,
2441        *expressions: t.Optional[ExpOrStr],
2442        append: bool = True,
2443        dialect: DialectType = None,
2444        copy: bool = True,
2445        **opts,
2446    ) -> Subqueryable:
2447        raise NotImplementedError("Subqueryable objects must implement `select`")
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:
2449    def with_(
2450        self,
2451        alias: ExpOrStr,
2452        as_: ExpOrStr,
2453        recursive: t.Optional[bool] = None,
2454        append: bool = True,
2455        dialect: DialectType = None,
2456        copy: bool = True,
2457        **opts,
2458    ) -> Subqueryable:
2459        """
2460        Append to or set the common table expressions.
2461
2462        Example:
2463            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2464            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2465
2466        Args:
2467            alias: the SQL code string to parse as the table name.
2468                If an `Expression` instance is passed, this is used as-is.
2469            as_: the SQL code string to parse as the table expression.
2470                If an `Expression` instance is passed, it will be used as-is.
2471            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2472            append: if `True`, add to any existing expressions.
2473                Otherwise, this resets the expressions.
2474            dialect: the dialect used to parse the input expression.
2475            copy: if `False`, modify this expression instance in-place.
2476            opts: other options to use to parse the input expressions.
2477
2478        Returns:
2479            The modified expression.
2480        """
2481        return _apply_cte_builder(
2482            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2483        )

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:
3258    def window(
3259        self,
3260        *expressions: t.Optional[ExpOrStr],
3261        append: bool = True,
3262        dialect: DialectType = None,
3263        copy: bool = True,
3264        **opts,
3265    ) -> Select:
3266        return _apply_list_builder(
3267            *expressions,
3268            instance=self,
3269            arg="windows",
3270            append=append,
3271            into=Window,
3272            dialect=dialect,
3273            copy=copy,
3274            **opts,
3275        )
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:
3277    def qualify(
3278        self,
3279        *expressions: t.Optional[ExpOrStr],
3280        append: bool = True,
3281        dialect: DialectType = None,
3282        copy: bool = True,
3283        **opts,
3284    ) -> Select:
3285        return _apply_conjunction_builder(
3286            *expressions,
3287            instance=self,
3288            arg="qualify",
3289            append=append,
3290            into=Qualify,
3291            dialect=dialect,
3292            copy=copy,
3293            **opts,
3294        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3296    def distinct(
3297        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3298    ) -> Select:
3299        """
3300        Set the OFFSET expression.
3301
3302        Example:
3303            >>> Select().from_("tbl").select("x").distinct().sql()
3304            'SELECT DISTINCT x FROM tbl'
3305
3306        Args:
3307            ons: the expressions to distinct on
3308            distinct: whether the Select should be distinct
3309            copy: if `False`, modify this expression instance in-place.
3310
3311        Returns:
3312            Select: the modified expression.
3313        """
3314        instance = maybe_copy(self, copy)
3315        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3316        instance.set("distinct", Distinct(on=on) if distinct else None)
3317        return instance

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:
3319    def ctas(
3320        self,
3321        table: ExpOrStr,
3322        properties: t.Optional[t.Dict] = None,
3323        dialect: DialectType = None,
3324        copy: bool = True,
3325        **opts,
3326    ) -> Create:
3327        """
3328        Convert this expression to a CREATE TABLE AS statement.
3329
3330        Example:
3331            >>> Select().select("*").from_("tbl").ctas("x").sql()
3332            'CREATE TABLE x AS SELECT * FROM tbl'
3333
3334        Args:
3335            table: the SQL code string to parse as the table name.
3336                If another `Expression` instance is passed, it will be used as-is.
3337            properties: an optional mapping of table properties
3338            dialect: the dialect used to parse the input table.
3339            copy: if `False`, modify this expression instance in-place.
3340            opts: other options to use to parse the input table.
3341
3342        Returns:
3343            The new Create expression.
3344        """
3345        instance = maybe_copy(self, copy)
3346        table_expression = maybe_parse(
3347            table,
3348            into=Table,
3349            dialect=dialect,
3350            **opts,
3351        )
3352        properties_expression = None
3353        if properties:
3354            properties_expression = Properties.from_dict(properties)
3355
3356        return Create(
3357            this=table_expression,
3358            kind="table",
3359            expression=instance,
3360            properties=properties_expression,
3361        )

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:
3363    def lock(self, update: bool = True, copy: bool = True) -> Select:
3364        """
3365        Set the locking read mode for this expression.
3366
3367        Examples:
3368            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3369            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3370
3371            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3372            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3373
3374        Args:
3375            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3376            copy: if `False`, modify this expression instance in-place.
3377
3378        Returns:
3379            The modified expression.
3380        """
3381        inst = maybe_copy(self, copy)
3382        inst.set("locks", [Lock(update=update)])
3383
3384        return inst

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:
3386    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3387        """
3388        Set hints for this expression.
3389
3390        Examples:
3391            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3392            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3393
3394        Args:
3395            hints: The SQL code strings to parse as the hints.
3396                If an `Expression` instance is passed, it will be used as-is.
3397            dialect: The dialect used to parse the hints.
3398            copy: If `False`, modify this expression instance in-place.
3399
3400        Returns:
3401            The modified expression.
3402        """
3403        inst = maybe_copy(self, copy)
3404        inst.set(
3405            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3406        )
3407
3408        return inst

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

Returns the first non subquery.

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

Tags are used for generating arbitrary sql like SELECT x.

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

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • kawrgs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
3767    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3768        """
3769        Checks whether this DataType matches one of the provided data types. Nested types or precision
3770        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3771
3772        Args:
3773            dtypes: the data types to compare this DataType to.
3774
3775        Returns:
3776            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3777        """
3778        for dtype in dtypes:
3779            other = DataType.build(dtype, udt=True)
3780
3781            if (
3782                other.expressions
3783                or self.this == DataType.Type.USERDEFINED
3784                or other.this == DataType.Type.USERDEFINED
3785            ):
3786                matches = self == other
3787            else:
3788                matches = self.this == other.this
3789
3790            if matches:
3791                return True
3792        return False

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):
3584    class Type(AutoName):
3585        ARRAY = auto()
3586        BIGDECIMAL = auto()
3587        BIGINT = auto()
3588        BIGSERIAL = auto()
3589        BINARY = auto()
3590        BIT = auto()
3591        BOOLEAN = auto()
3592        CHAR = auto()
3593        DATE = auto()
3594        DATEMULTIRANGE = auto()
3595        DATERANGE = auto()
3596        DATETIME = auto()
3597        DATETIME64 = auto()
3598        DECIMAL = auto()
3599        DOUBLE = auto()
3600        ENUM = auto()
3601        ENUM8 = auto()
3602        ENUM16 = auto()
3603        FIXEDSTRING = auto()
3604        FLOAT = auto()
3605        GEOGRAPHY = auto()
3606        GEOMETRY = auto()
3607        HLLSKETCH = auto()
3608        HSTORE = auto()
3609        IMAGE = auto()
3610        INET = auto()
3611        INT = auto()
3612        INT128 = auto()
3613        INT256 = auto()
3614        INT4MULTIRANGE = auto()
3615        INT4RANGE = auto()
3616        INT8MULTIRANGE = auto()
3617        INT8RANGE = auto()
3618        INTERVAL = auto()
3619        IPADDRESS = auto()
3620        IPPREFIX = auto()
3621        JSON = auto()
3622        JSONB = auto()
3623        LONGBLOB = auto()
3624        LONGTEXT = auto()
3625        LOWCARDINALITY = auto()
3626        MAP = auto()
3627        MEDIUMBLOB = auto()
3628        MEDIUMINT = auto()
3629        MEDIUMTEXT = auto()
3630        MONEY = auto()
3631        NCHAR = auto()
3632        NESTED = auto()
3633        NULL = auto()
3634        NULLABLE = auto()
3635        NUMMULTIRANGE = auto()
3636        NUMRANGE = auto()
3637        NVARCHAR = auto()
3638        OBJECT = auto()
3639        ROWVERSION = auto()
3640        SERIAL = auto()
3641        SET = auto()
3642        SMALLINT = auto()
3643        SMALLMONEY = auto()
3644        SMALLSERIAL = auto()
3645        STRUCT = auto()
3646        SUPER = auto()
3647        TEXT = auto()
3648        TINYBLOB = auto()
3649        TINYTEXT = auto()
3650        TIME = auto()
3651        TIMETZ = auto()
3652        TIMESTAMP = auto()
3653        TIMESTAMPLTZ = auto()
3654        TIMESTAMPTZ = auto()
3655        TIMESTAMP_S = auto()
3656        TIMESTAMP_MS = auto()
3657        TIMESTAMP_NS = auto()
3658        TINYINT = auto()
3659        TSMULTIRANGE = auto()
3660        TSRANGE = auto()
3661        TSTZMULTIRANGE = auto()
3662        TSTZRANGE = auto()
3663        UBIGINT = auto()
3664        UINT = auto()
3665        UINT128 = auto()
3666        UINT256 = auto()
3667        UMEDIUMINT = auto()
3668        UDECIMAL = auto()
3669        UNIQUEIDENTIFIER = auto()
3670        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3671        USERDEFINED = "USER-DEFINED"
3672        USMALLINT = auto()
3673        UTINYINT = auto()
3674        UUID = auto()
3675        VARBINARY = auto()
3676        VARCHAR = auto()
3677        VARIANT = auto()
3678        XML = auto()
3679        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
3799class PseudoType(DataType):
3800    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3804class ObjectIdentifier(DataType):
3805    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3809class SubqueryPredicate(Predicate):
3810    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3813class All(SubqueryPredicate):
3814    pass
key = 'all'
class Any(SubqueryPredicate):
3817class Any(SubqueryPredicate):
3818    pass
key = 'any'
class Exists(SubqueryPredicate):
3821class Exists(SubqueryPredicate):
3822    pass
key = 'exists'
class Command(Expression):
3827class Command(Expression):
3828    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3831class Transaction(Expression):
3832    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3835class Commit(Expression):
3836    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3839class Rollback(Expression):
3840    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3843class AlterTable(Expression):
3844    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):
3847class AddConstraint(Expression):
3848    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3851class DropPartition(Expression):
3852    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3856class Binary(Condition):
3857    arg_types = {"this": True, "expression": True}
3858
3859    @property
3860    def left(self) -> Expression:
3861        return self.this
3862
3863    @property
3864    def right(self) -> Expression:
3865        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
right: Expression
key = 'binary'
class Add(Binary):
3868class Add(Binary):
3869    pass
key = 'add'
class Connector(Binary):
3872class Connector(Binary):
3873    pass
key = 'connector'
class And(Connector):
3876class And(Connector):
3877    pass
key = 'and'
class Or(Connector):
3880class Or(Connector):
3881    pass
key = 'or'
class BitwiseAnd(Binary):
3884class BitwiseAnd(Binary):
3885    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3888class BitwiseLeftShift(Binary):
3889    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3892class BitwiseOr(Binary):
3893    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3896class BitwiseRightShift(Binary):
3897    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3900class BitwiseXor(Binary):
3901    pass
key = 'bitwisexor'
class Div(Binary):
3904class Div(Binary):
3905    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):
3908class Overlaps(Binary):
3909    pass
key = 'overlaps'
class Dot(Binary):
3912class Dot(Binary):
3913    @property
3914    def name(self) -> str:
3915        return self.expression.name
3916
3917    @property
3918    def output_name(self) -> str:
3919        return self.name
3920
3921    @classmethod
3922    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3923        """Build a Dot object with a sequence of expressions."""
3924        if len(expressions) < 2:
3925            raise ValueError(f"Dot requires >= 2 expressions.")
3926
3927        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
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:
3921    @classmethod
3922    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3923        """Build a Dot object with a sequence of expressions."""
3924        if len(expressions) < 2:
3925            raise ValueError(f"Dot requires >= 2 expressions.")
3926
3927        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

key = 'dot'
class DPipe(Binary):
3930class DPipe(Binary):
3931    pass
key = 'dpipe'
class SafeDPipe(DPipe):
3934class SafeDPipe(DPipe):
3935    pass
key = 'safedpipe'
class EQ(Binary, Predicate):
3938class EQ(Binary, Predicate):
3939    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3942class NullSafeEQ(Binary, Predicate):
3943    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3946class NullSafeNEQ(Binary, Predicate):
3947    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3951class PropertyEQ(Binary):
3952    pass
key = 'propertyeq'
class Distance(Binary):
3955class Distance(Binary):
3956    pass
key = 'distance'
class Escape(Binary):
3959class Escape(Binary):
3960    pass
key = 'escape'
class Glob(Binary, Predicate):
3963class Glob(Binary, Predicate):
3964    pass
key = 'glob'
class GT(Binary, Predicate):
3967class GT(Binary, Predicate):
3968    pass
key = 'gt'
class GTE(Binary, Predicate):
3971class GTE(Binary, Predicate):
3972    pass
key = 'gte'
class ILike(Binary, Predicate):
3975class ILike(Binary, Predicate):
3976    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3979class ILikeAny(Binary, Predicate):
3980    pass
key = 'ilikeany'
class IntDiv(Binary):
3983class IntDiv(Binary):
3984    pass
key = 'intdiv'
class Is(Binary, Predicate):
3987class Is(Binary, Predicate):
3988    pass
key = 'is'
class Kwarg(Binary):
3991class Kwarg(Binary):
3992    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
3995class Like(Binary, Predicate):
3996    pass
key = 'like'
class LikeAny(Binary, Predicate):
3999class LikeAny(Binary, Predicate):
4000    pass
key = 'likeany'
class LT(Binary, Predicate):
4003class LT(Binary, Predicate):
4004    pass
key = 'lt'
class LTE(Binary, Predicate):
4007class LTE(Binary, Predicate):
4008    pass
key = 'lte'
class Mod(Binary):
4011class Mod(Binary):
4012    pass
key = 'mod'
class Mul(Binary):
4015class Mul(Binary):
4016    pass
key = 'mul'
class NEQ(Binary, Predicate):
4019class NEQ(Binary, Predicate):
4020    pass
key = 'neq'
class SimilarTo(Binary, Predicate):
4023class SimilarTo(Binary, Predicate):
4024    pass
key = 'similarto'
class Slice(Binary):
4027class Slice(Binary):
4028    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4031class Sub(Binary):
4032    pass
key = 'sub'
class ArrayOverlaps(Binary):
4035class ArrayOverlaps(Binary):
4036    pass
key = 'arrayoverlaps'
class Unary(Condition):
4041class Unary(Condition):
4042    pass
key = 'unary'
class BitwiseNot(Unary):
4045class BitwiseNot(Unary):
4046    pass
key = 'bitwisenot'
class Not(Unary):
4049class Not(Unary):
4050    pass
key = 'not'
class Paren(Unary):
4053class Paren(Unary):
4054    arg_types = {"this": True, "with": False}
4055
4056    @property
4057    def output_name(self) -> str:
4058        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):
4061class Neg(Unary):
4062    pass
key = 'neg'
class Alias(Expression):
4065class Alias(Expression):
4066    arg_types = {"this": True, "alias": False}
4067
4068    @property
4069    def output_name(self) -> str:
4070        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):
4073class Aliases(Expression):
4074    arg_types = {"this": True, "expressions": True}
4075
4076    @property
4077    def aliases(self):
4078        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
4081class AtTimeZone(Expression):
4082    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4085class Between(Predicate):
4086    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4089class Bracket(Condition):
4090    arg_types = {"this": True, "expressions": True}
4091
4092    @property
4093    def output_name(self) -> str:
4094        if len(self.expressions) == 1:
4095            return self.expressions[0].output_name
4096
4097        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):
4100class SafeBracket(Bracket):
4101    """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):
4104class Distinct(Expression):
4105    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4108class In(Predicate):
4109    arg_types = {
4110        "this": True,
4111        "expressions": False,
4112        "query": False,
4113        "unnest": False,
4114        "field": False,
4115        "is_global": False,
4116    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4120class ForIn(Expression):
4121    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4124class TimeUnit(Expression):
4125    """Automatically converts unit arg into a var."""
4126
4127    arg_types = {"unit": False}
4128
4129    UNABBREVIATED_UNIT_NAME = {
4130        "d": "day",
4131        "h": "hour",
4132        "m": "minute",
4133        "ms": "millisecond",
4134        "ns": "nanosecond",
4135        "q": "quarter",
4136        "s": "second",
4137        "us": "microsecond",
4138        "w": "week",
4139        "y": "year",
4140    }
4141
4142    VAR_LIKE = (Column, Literal, Var)
4143
4144    def __init__(self, **args):
4145        unit = args.get("unit")
4146        if isinstance(unit, self.VAR_LIKE):
4147            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4148        elif isinstance(unit, Week):
4149            unit.set("this", Var(this=unit.this.name))
4150
4151        super().__init__(**args)
4152
4153    @property
4154    def unit(self) -> t.Optional[Var]:
4155        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4144    def __init__(self, **args):
4145        unit = args.get("unit")
4146        if isinstance(unit, self.VAR_LIKE):
4147            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
4148        elif isinstance(unit, Week):
4149            unit.set("this", Var(this=unit.this.name))
4150
4151        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):
4158class IntervalOp(TimeUnit):
4159    arg_types = {"unit": True, "expression": True}
4160
4161    def interval(self):
4162        return Interval(
4163            this=self.expression.copy(),
4164            unit=self.unit.copy(),
4165        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4161    def interval(self):
4162        return Interval(
4163            this=self.expression.copy(),
4164            unit=self.unit.copy(),
4165        )
key = 'intervalop'
class IntervalSpan(DataType):
4171class IntervalSpan(DataType):
4172    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4175class Interval(TimeUnit):
4176    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4179class IgnoreNulls(Expression):
4180    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4183class RespectNulls(Expression):
4184    pass
key = 'respectnulls'
class Func(Condition):
4188class Func(Condition):
4189    """
4190    The base class for all function expressions.
4191
4192    Attributes:
4193        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4194            treated as a variable length argument and the argument's value will be stored as a list.
4195        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4196            for this function expression. These values are used to map this node to a name during parsing
4197            as well as to provide the function's name during SQL string generation. By default the SQL
4198            name is set to the expression's class name transformed to snake case.
4199    """
4200
4201    is_var_len_args = False
4202
4203    @classmethod
4204    def from_arg_list(cls, args):
4205        if cls.is_var_len_args:
4206            all_arg_keys = list(cls.arg_types)
4207            # If this function supports variable length argument treat the last argument as such.
4208            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4209            num_non_var = len(non_var_len_arg_keys)
4210
4211            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4212            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4213        else:
4214            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4215
4216        return cls(**args_dict)
4217
4218    @classmethod
4219    def sql_names(cls):
4220        if cls is Func:
4221            raise NotImplementedError(
4222                "SQL name is only supported by concrete function implementations"
4223            )
4224        if "_sql_names" not in cls.__dict__:
4225            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4226        return cls._sql_names
4227
4228    @classmethod
4229    def sql_name(cls):
4230        return cls.sql_names()[0]
4231
4232    @classmethod
4233    def default_parser_mappings(cls):
4234        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):
4203    @classmethod
4204    def from_arg_list(cls, args):
4205        if cls.is_var_len_args:
4206            all_arg_keys = list(cls.arg_types)
4207            # If this function supports variable length argument treat the last argument as such.
4208            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4209            num_non_var = len(non_var_len_arg_keys)
4210
4211            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4212            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4213        else:
4214            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4215
4216        return cls(**args_dict)
@classmethod
def sql_names(cls):
4218    @classmethod
4219    def sql_names(cls):
4220        if cls is Func:
4221            raise NotImplementedError(
4222                "SQL name is only supported by concrete function implementations"
4223            )
4224        if "_sql_names" not in cls.__dict__:
4225            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4226        return cls._sql_names
@classmethod
def sql_name(cls):
4228    @classmethod
4229    def sql_name(cls):
4230        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4232    @classmethod
4233    def default_parser_mappings(cls):
4234        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4237class AggFunc(Func):
4238    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4241class ParameterizedAgg(AggFunc):
4242    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4245class Abs(Func):
4246    pass
key = 'abs'
class ArgMax(AggFunc):
4249class ArgMax(AggFunc):
4250    arg_types = {"this": True, "expression": True, "count": False}
4251    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4254class ArgMin(AggFunc):
4255    arg_types = {"this": True, "expression": True, "count": False}
4256    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4259class ApproxTopK(AggFunc):
4260    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4263class Flatten(Func):
4264    pass
key = 'flatten'
class Transform(Func):
4268class Transform(Func):
4269    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4272class Anonymous(Func):
4273    arg_types = {"this": True, "expressions": False}
4274    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4279class Hll(AggFunc):
4280    arg_types = {"this": True, "expressions": False}
4281    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4284class ApproxDistinct(AggFunc):
4285    arg_types = {"this": True, "accuracy": False}
4286    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4289class Array(Func):
4290    arg_types = {"expressions": False}
4291    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4296class ToChar(Func):
4297    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4300class GenerateSeries(Func):
4301    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4304class ArrayAgg(AggFunc):
4305    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4308class ArrayUniqueAgg(AggFunc):
4309    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4312class ArrayAll(Func):
4313    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4316class ArrayAny(Func):
4317    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4320class ArrayConcat(Func):
4321    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4322    arg_types = {"this": True, "expressions": False}
4323    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4326class ArrayContains(Binary, Func):
4327    pass
key = 'arraycontains'
class ArrayContained(Binary):
4330class ArrayContained(Binary):
4331    pass
key = 'arraycontained'
class ArrayFilter(Func):
4334class ArrayFilter(Func):
4335    arg_types = {"this": True, "expression": True}
4336    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4339class ArrayJoin(Func):
4340    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4343class ArraySize(Func):
4344    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4347class ArraySort(Func):
4348    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4351class ArraySum(Func):
4352    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4355class ArrayUnionAgg(AggFunc):
4356    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4359class Avg(AggFunc):
4360    pass
key = 'avg'
class AnyValue(AggFunc):
4363class AnyValue(AggFunc):
4364    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):
4367class First(Func):
4368    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4371class Last(Func):
4372    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4375class Case(Func):
4376    arg_types = {"this": False, "ifs": True, "default": False}
4377
4378    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4379        instance = maybe_copy(self, copy)
4380        instance.append(
4381            "ifs",
4382            If(
4383                this=maybe_parse(condition, copy=copy, **opts),
4384                true=maybe_parse(then, copy=copy, **opts),
4385            ),
4386        )
4387        return instance
4388
4389    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4390        instance = maybe_copy(self, copy)
4391        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4392        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:
4378    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4379        instance = maybe_copy(self, copy)
4380        instance.append(
4381            "ifs",
4382            If(
4383                this=maybe_parse(condition, copy=copy, **opts),
4384                true=maybe_parse(then, copy=copy, **opts),
4385            ),
4386        )
4387        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4389    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4390        instance = maybe_copy(self, copy)
4391        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4392        return instance
key = 'case'
class Cast(Func):
4395class Cast(Func):
4396    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4397
4398    @property
4399    def name(self) -> str:
4400        return self.this.name
4401
4402    @property
4403    def to(self) -> DataType:
4404        return self.args["to"]
4405
4406    @property
4407    def output_name(self) -> str:
4408        return self.name
4409
4410    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4411        """
4412        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4413        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4414        array<int> != array<float>.
4415
4416        Args:
4417            dtypes: the data types to compare this Cast's DataType to.
4418
4419        Returns:
4420            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4421        """
4422        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
to: DataType
output_name: str

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4410    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4411        """
4412        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4413        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4414        array<int> != array<float>.
4415
4416        Args:
4417            dtypes: the data types to compare this Cast's DataType to.
4418
4419        Returns:
4420            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4421        """
4422        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):
4425class TryCast(Cast):
4426    pass
key = 'trycast'
class CastToStrType(Func):
4429class CastToStrType(Func):
4430    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4433class Collate(Binary, Func):
4434    pass
key = 'collate'
class Ceil(Func):
4437class Ceil(Func):
4438    arg_types = {"this": True, "decimals": False}
4439    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4442class Coalesce(Func):
4443    arg_types = {"this": True, "expressions": False}
4444    is_var_len_args = True
4445    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4448class Chr(Func):
4449    arg_types = {"this": True, "charset": False, "expressions": False}
4450    is_var_len_args = True
4451    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4454class Concat(Func):
4455    arg_types = {"expressions": True}
4456    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4459class SafeConcat(Concat):
4460    pass
key = 'safeconcat'
class ConcatWs(Concat):
4463class ConcatWs(Concat):
4464    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4467class Count(AggFunc):
4468    arg_types = {"this": False, "expressions": False}
4469    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4472class CountIf(AggFunc):
4473    pass
key = 'countif'
class CurrentDate(Func):
4476class CurrentDate(Func):
4477    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4480class CurrentDatetime(Func):
4481    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4484class CurrentTime(Func):
4485    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4488class CurrentTimestamp(Func):
4489    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4492class CurrentUser(Func):
4493    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4496class DateAdd(Func, IntervalOp):
4497    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4500class DateSub(Func, IntervalOp):
4501    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4504class DateDiff(Func, TimeUnit):
4505    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4506    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4509class DateTrunc(Func):
4510    arg_types = {"unit": True, "this": True, "zone": False}
4511
4512    @property
4513    def unit(self) -> Expression:
4514        return self.args["unit"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4517class DatetimeAdd(Func, IntervalOp):
4518    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4521class DatetimeSub(Func, IntervalOp):
4522    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4525class DatetimeDiff(Func, TimeUnit):
4526    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4529class DatetimeTrunc(Func, TimeUnit):
4530    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4533class DayOfWeek(Func):
4534    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4537class DayOfMonth(Func):
4538    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4541class DayOfYear(Func):
4542    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4545class ToDays(Func):
4546    pass
key = 'todays'
class WeekOfYear(Func):
4549class WeekOfYear(Func):
4550    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4553class MonthsBetween(Func):
4554    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4557class LastDateOfMonth(Func):
4558    pass
key = 'lastdateofmonth'
class Extract(Func):
4561class Extract(Func):
4562    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4565class Timestamp(Func):
4566    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4569class TimestampAdd(Func, TimeUnit):
4570    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4573class TimestampSub(Func, TimeUnit):
4574    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4577class TimestampDiff(Func, TimeUnit):
4578    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4581class TimestampTrunc(Func, TimeUnit):
4582    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4585class TimeAdd(Func, TimeUnit):
4586    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4589class TimeSub(Func, TimeUnit):
4590    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4593class TimeDiff(Func, TimeUnit):
4594    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4597class TimeTrunc(Func, TimeUnit):
4598    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4601class DateFromParts(Func):
4602    _sql_names = ["DATEFROMPARTS"]
4603    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4606class DateStrToDate(Func):
4607    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4610class DateToDateStr(Func):
4611    pass
key = 'datetodatestr'
class DateToDi(Func):
4614class DateToDi(Func):
4615    pass
key = 'datetodi'
class Date(Func):
4619class Date(Func):
4620    arg_types = {"this": False, "zone": False, "expressions": False}
4621    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4624class Day(Func):
4625    pass
key = 'day'
class Decode(Func):
4628class Decode(Func):
4629    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4632class DiToDate(Func):
4633    pass
key = 'ditodate'
class Encode(Func):
4636class Encode(Func):
4637    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4640class Exp(Func):
4641    pass
key = 'exp'
class Explode(Func):
4645class Explode(Func):
4646    arg_types = {"this": True, "expressions": False}
4647    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4650class ExplodeOuter(Explode):
4651    pass
key = 'explodeouter'
class Posexplode(Explode):
4654class Posexplode(Explode):
4655    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4658class PosexplodeOuter(Posexplode):
4659    pass
key = 'posexplodeouter'
class Floor(Func):
4662class Floor(Func):
4663    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4666class FromBase64(Func):
4667    pass
key = 'frombase64'
class ToBase64(Func):
4670class ToBase64(Func):
4671    pass
key = 'tobase64'
class Greatest(Func):
4674class Greatest(Func):
4675    arg_types = {"this": True, "expressions": False}
4676    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4679class GroupConcat(AggFunc):
4680    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4683class Hex(Func):
4684    pass
key = 'hex'
class Xor(Connector, Func):
4687class Xor(Connector, Func):
4688    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4691class If(Func):
4692    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4695class Nullif(Func):
4696    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4699class Initcap(Func):
4700    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4703class IsNan(Func):
4704    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4707class IsInf(Func):
4708    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4711class FormatJson(Expression):
4712    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4715class JSONKeyValue(Expression):
4716    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4719class JSONObject(Func):
4720    arg_types = {
4721        "expressions": False,
4722        "null_handling": False,
4723        "unique_keys": False,
4724        "return_type": False,
4725        "encoding": False,
4726    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4730class JSONArray(Func):
4731    arg_types = {
4732        "expressions": True,
4733        "null_handling": False,
4734        "return_type": False,
4735        "strict": False,
4736    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4740class JSONArrayAgg(Func):
4741    arg_types = {
4742        "this": True,
4743        "order": False,
4744        "null_handling": False,
4745        "return_type": False,
4746        "strict": False,
4747    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4752class JSONColumnDef(Expression):
4753    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):
4756class JSONSchema(Expression):
4757    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4761class JSONTable(Func):
4762    arg_types = {
4763        "this": True,
4764        "schema": True,
4765        "path": False,
4766        "error_handling": False,
4767        "empty_handling": False,
4768    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4771class OpenJSONColumnDef(Expression):
4772    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):
4775class OpenJSON(Func):
4776    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4779class JSONBContains(Binary):
4780    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4783class JSONExtract(Binary, Func):
4784    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4787class JSONExtractScalar(JSONExtract):
4788    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4791class JSONBExtract(JSONExtract):
4792    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4795class JSONBExtractScalar(JSONExtract):
4796    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4799class JSONFormat(Func):
4800    arg_types = {"this": False, "options": False}
4801    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4805class JSONArrayContains(Binary, Predicate, Func):
4806    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4809class ParseJSON(Func):
4810    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4811    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4812    arg_types = {"this": True, "expressions": False}
4813    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
4816class Least(Func):
4817    arg_types = {"this": True, "expressions": False}
4818    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4821class Left(Func):
4822    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4829class Length(Func):
4830    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4833class Levenshtein(Func):
4834    arg_types = {
4835        "this": True,
4836        "expression": False,
4837        "ins_cost": False,
4838        "del_cost": False,
4839        "sub_cost": False,
4840    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4843class Ln(Func):
4844    pass
key = 'ln'
class Log(Func):
4847class Log(Func):
4848    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4851class Log2(Func):
4852    pass
key = 'log2'
class Log10(Func):
4855class Log10(Func):
4856    pass
key = 'log10'
class LogicalOr(AggFunc):
4859class LogicalOr(AggFunc):
4860    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4863class LogicalAnd(AggFunc):
4864    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4867class Lower(Func):
4868    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4871class Map(Func):
4872    arg_types = {"keys": False, "values": False}
4873
4874    @property
4875    def keys(self) -> t.List[Expression]:
4876        keys = self.args.get("keys")
4877        return keys.expressions if keys else []
4878
4879    @property
4880    def values(self) -> t.List[Expression]:
4881        values = self.args.get("values")
4882        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
values: List[Expression]
key = 'map'
class MapFromEntries(Func):
4885class MapFromEntries(Func):
4886    pass
key = 'mapfromentries'
class StarMap(Func):
4889class StarMap(Func):
4890    pass
key = 'starmap'
class VarMap(Func):
4893class VarMap(Func):
4894    arg_types = {"keys": True, "values": True}
4895    is_var_len_args = True
4896
4897    @property
4898    def keys(self) -> t.List[Expression]:
4899        return self.args["keys"].expressions
4900
4901    @property
4902    def values(self) -> t.List[Expression]:
4903        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):
4907class MatchAgainst(Func):
4908    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4911class Max(AggFunc):
4912    arg_types = {"this": True, "expressions": False}
4913    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4916class MD5(Func):
4917    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4921class MD5Digest(Func):
4922    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4925class Min(AggFunc):
4926    arg_types = {"this": True, "expressions": False}
4927    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4930class Month(Func):
4931    pass
key = 'month'
class Nvl2(Func):
4934class Nvl2(Func):
4935    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
4939class Predict(Func):
4940    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
4943class Pow(Binary, Func):
4944    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4947class PercentileCont(AggFunc):
4948    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4951class PercentileDisc(AggFunc):
4952    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4955class Quantile(AggFunc):
4956    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4959class ApproxQuantile(Quantile):
4960    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):
4963class RangeN(Func):
4964    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4967class ReadCSV(Func):
4968    _sql_names = ["READ_CSV"]
4969    is_var_len_args = True
4970    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4973class Reduce(Func):
4974    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):
4977class RegexpExtract(Func):
4978    arg_types = {
4979        "this": True,
4980        "expression": True,
4981        "position": False,
4982        "occurrence": False,
4983        "parameters": False,
4984        "group": False,
4985    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
4988class RegexpReplace(Func):
4989    arg_types = {
4990        "this": True,
4991        "expression": True,
4992        "replacement": True,
4993        "position": False,
4994        "occurrence": False,
4995        "parameters": False,
4996        "modifiers": False,
4997    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5000class RegexpLike(Binary, Func):
5001    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5004class RegexpILike(Binary, Func):
5005    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5010class RegexpSplit(Func):
5011    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5014class Repeat(Func):
5015    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5018class Round(Func):
5019    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5022class RowNumber(Func):
5023    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5026class SafeDivide(Func):
5027    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5030class SHA(Func):
5031    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5034class SHA2(Func):
5035    _sql_names = ["SHA2"]
5036    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5039class SortArray(Func):
5040    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5043class Split(Func):
5044    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5049class Substring(Func):
5050    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5053class StandardHash(Func):
5054    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5057class StartsWith(Func):
5058    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5059    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5062class StrPosition(Func):
5063    arg_types = {
5064        "this": True,
5065        "substr": True,
5066        "position": False,
5067        "instance": False,
5068    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5071class StrToDate(Func):
5072    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5075class StrToTime(Func):
5076    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5081class StrToUnix(Func):
5082    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5087class StrToMap(Func):
5088    arg_types = {
5089        "this": True,
5090        "pair_delim": False,
5091        "key_value_delim": False,
5092        "duplicate_resolution_callback": False,
5093    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5096class NumberToStr(Func):
5097    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5100class FromBase(Func):
5101    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5104class Struct(Func):
5105    arg_types = {"expressions": False}
5106    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5109class StructExtract(Func):
5110    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5115class Stuff(Func):
5116    _sql_names = ["STUFF", "INSERT"]
5117    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):
5120class Sum(AggFunc):
5121    pass
key = 'sum'
class Sqrt(Func):
5124class Sqrt(Func):
5125    pass
key = 'sqrt'
class Stddev(AggFunc):
5128class Stddev(AggFunc):
5129    pass
key = 'stddev'
class StddevPop(AggFunc):
5132class StddevPop(AggFunc):
5133    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5136class StddevSamp(AggFunc):
5137    pass
key = 'stddevsamp'
class TimeToStr(Func):
5140class TimeToStr(Func):
5141    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5144class TimeToTimeStr(Func):
5145    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5148class TimeToUnix(Func):
5149    pass
key = 'timetounix'
class TimeStrToDate(Func):
5152class TimeStrToDate(Func):
5153    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5156class TimeStrToTime(Func):
5157    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5160class TimeStrToUnix(Func):
5161    pass
key = 'timestrtounix'
class Trim(Func):
5164class Trim(Func):
5165    arg_types = {
5166        "this": True,
5167        "expression": False,
5168        "position": False,
5169        "collation": False,
5170    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5173class TsOrDsAdd(Func, TimeUnit):
5174    # return_type is used to correctly cast the arguments of this expression when transpiling it
5175    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5176
5177    @property
5178    def return_type(self) -> DataType:
5179        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
arg_types = {'this': True, 'expression': True, 'unit': False, 'return_type': False}
return_type: DataType
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5182class TsOrDsDiff(Func, TimeUnit):
5183    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5186class TsOrDsToDateStr(Func):
5187    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5190class TsOrDsToDate(Func):
5191    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
5194class TsOrDiToDi(Func):
5195    pass
key = 'tsorditodi'
class Unhex(Func):
5198class Unhex(Func):
5199    pass
key = 'unhex'
class UnixToStr(Func):
5202class UnixToStr(Func):
5203    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5208class UnixToTime(Func):
5209    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5210
5211    SECONDS = Literal.string("seconds")
5212    MILLIS = Literal.string("millis")
5213    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):
5216class UnixToTimeStr(Func):
5217    pass
key = 'unixtotimestr'
class Upper(Func):
5220class Upper(Func):
5221    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5224class Variance(AggFunc):
5225    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5228class VariancePop(AggFunc):
5229    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5232class Week(Func):
5233    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5236class XMLTable(Func):
5237    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):
5240class Year(Func):
5241    pass
key = 'year'
class Use(Expression):
5244class Use(Expression):
5245    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5248class Merge(Expression):
5249    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):
5252class When(Func):
5253    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):
5258class NextValueFor(Func):
5259    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONTable'>, <class 'Last'>, <class 'LastDateOfMonth'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeConcat'>, <class 'SafeDivide'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'Unhex'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
5296def maybe_parse(
5297    sql_or_expression: ExpOrStr,
5298    *,
5299    into: t.Optional[IntoType] = None,
5300    dialect: DialectType = None,
5301    prefix: t.Optional[str] = None,
5302    copy: bool = False,
5303    **opts,
5304) -> Expression:
5305    """Gracefully handle a possible string or expression.
5306
5307    Example:
5308        >>> maybe_parse("1")
5309        (LITERAL this: 1, is_string: False)
5310        >>> maybe_parse(to_identifier("x"))
5311        (IDENTIFIER this: x, quoted: False)
5312
5313    Args:
5314        sql_or_expression: the SQL code string or an expression
5315        into: the SQLGlot Expression to parse into
5316        dialect: the dialect used to parse the input expressions (in the case that an
5317            input expression is a SQL string).
5318        prefix: a string to prefix the sql with before it gets parsed
5319            (automatically includes a space)
5320        copy: whether or not to copy the expression.
5321        **opts: other options to use to parse the input expressions (again, in the case
5322            that an input expression is a SQL string).
5323
5324    Returns:
5325        Expression: the parsed or given expression.
5326    """
5327    if isinstance(sql_or_expression, Expression):
5328        if copy:
5329            return sql_or_expression.copy()
5330        return sql_or_expression
5331
5332    if sql_or_expression is None:
5333        raise ParseError(f"SQL cannot be None")
5334
5335    import sqlglot
5336
5337    sql = str(sql_or_expression)
5338    if prefix:
5339        sql = f"{prefix} {sql}"
5340
5341    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):
5354def maybe_copy(instance, copy=True):
5355    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:
5536def union(
5537    left: ExpOrStr,
5538    right: ExpOrStr,
5539    distinct: bool = True,
5540    dialect: DialectType = None,
5541    copy: bool = True,
5542    **opts,
5543) -> Union:
5544    """
5545    Initializes a syntax tree from one UNION expression.
5546
5547    Example:
5548        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5549        'SELECT * FROM foo UNION SELECT * FROM bla'
5550
5551    Args:
5552        left: the SQL code string corresponding to the left-hand side.
5553            If an `Expression` instance is passed, it will be used as-is.
5554        right: the SQL code string corresponding to the right-hand side.
5555            If an `Expression` instance is passed, it will be used as-is.
5556        distinct: set the DISTINCT flag if and only if this is true.
5557        dialect: the dialect used to parse the input expression.
5558        copy: whether or not to copy the expression.
5559        opts: other options to use to parse the input expressions.
5560
5561    Returns:
5562        The new Union instance.
5563    """
5564    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5565    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5566
5567    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:
5570def intersect(
5571    left: ExpOrStr,
5572    right: ExpOrStr,
5573    distinct: bool = True,
5574    dialect: DialectType = None,
5575    copy: bool = True,
5576    **opts,
5577) -> Intersect:
5578    """
5579    Initializes a syntax tree from one INTERSECT expression.
5580
5581    Example:
5582        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5583        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5584
5585    Args:
5586        left: the SQL code string corresponding to the left-hand side.
5587            If an `Expression` instance is passed, it will be used as-is.
5588        right: the SQL code string corresponding to the right-hand side.
5589            If an `Expression` instance is passed, it will be used as-is.
5590        distinct: set the DISTINCT flag if and only if this is true.
5591        dialect: the dialect used to parse the input expression.
5592        copy: whether or not to copy the expression.
5593        opts: other options to use to parse the input expressions.
5594
5595    Returns:
5596        The new Intersect instance.
5597    """
5598    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5599    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5600
5601    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:
5604def except_(
5605    left: ExpOrStr,
5606    right: ExpOrStr,
5607    distinct: bool = True,
5608    dialect: DialectType = None,
5609    copy: bool = True,
5610    **opts,
5611) -> Except:
5612    """
5613    Initializes a syntax tree from one EXCEPT expression.
5614
5615    Example:
5616        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5617        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5618
5619    Args:
5620        left: the SQL code string corresponding to the left-hand side.
5621            If an `Expression` instance is passed, it will be used as-is.
5622        right: the SQL code string corresponding to the right-hand side.
5623            If an `Expression` instance is passed, it will be used as-is.
5624        distinct: set the DISTINCT flag if and only if this is true.
5625        dialect: the dialect used to parse the input expression.
5626        copy: whether or not to copy the expression.
5627        opts: other options to use to parse the input expressions.
5628
5629    Returns:
5630        The new Except instance.
5631    """
5632    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5633    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5634
5635    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:
5638def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5639    """
5640    Initializes a syntax tree from one or multiple SELECT expressions.
5641
5642    Example:
5643        >>> select("col1", "col2").from_("tbl").sql()
5644        'SELECT col1, col2 FROM tbl'
5645
5646    Args:
5647        *expressions: the SQL code string to parse as the expressions of a
5648            SELECT statement. If an Expression instance is passed, this is used as-is.
5649        dialect: the dialect used to parse the input expressions (in the case that an
5650            input expression is a SQL string).
5651        **opts: other options to use to parse the input expressions (again, in the case
5652            that an input expression is a SQL string).
5653
5654    Returns:
5655        Select: the syntax tree for the SELECT statement.
5656    """
5657    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:
5660def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5661    """
5662    Initializes a syntax tree from a FROM expression.
5663
5664    Example:
5665        >>> from_("tbl").select("col1", "col2").sql()
5666        'SELECT col1, col2 FROM tbl'
5667
5668    Args:
5669        *expression: the SQL code string to parse as the FROM expressions of a
5670            SELECT statement. If an Expression instance is passed, this is used as-is.
5671        dialect: the dialect used to parse the input expression (in the case that the
5672            input expression is a SQL string).
5673        **opts: other options to use to parse the input expressions (again, in the case
5674            that the input expression is a SQL string).
5675
5676    Returns:
5677        Select: the syntax tree for the SELECT statement.
5678    """
5679    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:
5682def update(
5683    table: str | Table,
5684    properties: dict,
5685    where: t.Optional[ExpOrStr] = None,
5686    from_: t.Optional[ExpOrStr] = None,
5687    dialect: DialectType = None,
5688    **opts,
5689) -> Update:
5690    """
5691    Creates an update statement.
5692
5693    Example:
5694        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5695        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5696
5697    Args:
5698        *properties: dictionary of properties to set which are
5699            auto converted to sql objects eg None -> NULL
5700        where: sql conditional parsed into a WHERE statement
5701        from_: sql statement parsed into a FROM statement
5702        dialect: the dialect used to parse the input expressions.
5703        **opts: other options to use to parse the input expressions.
5704
5705    Returns:
5706        Update: the syntax tree for the UPDATE statement.
5707    """
5708    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5709    update_expr.set(
5710        "expressions",
5711        [
5712            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5713            for k, v in properties.items()
5714        ],
5715    )
5716    if from_:
5717        update_expr.set(
5718            "from",
5719            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5720        )
5721    if isinstance(where, Condition):
5722        where = Where(this=where)
5723    if where:
5724        update_expr.set(
5725            "where",
5726            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5727        )
5728    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:
5731def delete(
5732    table: ExpOrStr,
5733    where: t.Optional[ExpOrStr] = None,
5734    returning: t.Optional[ExpOrStr] = None,
5735    dialect: DialectType = None,
5736    **opts,
5737) -> Delete:
5738    """
5739    Builds a delete statement.
5740
5741    Example:
5742        >>> delete("my_table", where="id > 1").sql()
5743        'DELETE FROM my_table WHERE id > 1'
5744
5745    Args:
5746        where: sql conditional parsed into a WHERE statement
5747        returning: sql conditional parsed into a RETURNING statement
5748        dialect: the dialect used to parse the input expressions.
5749        **opts: other options to use to parse the input expressions.
5750
5751    Returns:
5752        Delete: the syntax tree for the DELETE statement.
5753    """
5754    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5755    if where:
5756        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5757    if returning:
5758        delete_expr = t.cast(
5759            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5760        )
5761    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[Union[str, Expression]]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
5764def insert(
5765    expression: ExpOrStr,
5766    into: ExpOrStr,
5767    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5768    overwrite: t.Optional[bool] = None,
5769    returning: t.Optional[ExpOrStr] = None,
5770    dialect: DialectType = None,
5771    copy: bool = True,
5772    **opts,
5773) -> Insert:
5774    """
5775    Builds an INSERT statement.
5776
5777    Example:
5778        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5779        'INSERT INTO tbl VALUES (1, 2, 3)'
5780
5781    Args:
5782        expression: the sql string or expression of the INSERT statement
5783        into: the tbl to insert data to.
5784        columns: optionally the table's column names.
5785        overwrite: whether to INSERT OVERWRITE or not.
5786        returning: sql conditional parsed into a RETURNING statement
5787        dialect: the dialect used to parse the input expressions.
5788        copy: whether or not to copy the expression.
5789        **opts: other options to use to parse the input expressions.
5790
5791    Returns:
5792        Insert: the syntax tree for the INSERT statement.
5793    """
5794    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5795    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5796
5797    if columns:
5798        this = _apply_list_builder(
5799            *columns,
5800            instance=Schema(this=this),
5801            arg="expressions",
5802            into=Identifier,
5803            copy=False,
5804            dialect=dialect,
5805            **opts,
5806        )
5807
5808    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5809
5810    if returning:
5811        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5812
5813    return insert

Builds an INSERT statement.

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

Insert: the syntax tree for the INSERT statement.

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

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:
5853def and_(
5854    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5855) -> Condition:
5856    """
5857    Combine multiple conditions with an AND logical operator.
5858
5859    Example:
5860        >>> and_("x=1", and_("y=1", "z=1")).sql()
5861        'x = 1 AND (y = 1 AND z = 1)'
5862
5863    Args:
5864        *expressions: the SQL code strings to parse.
5865            If an Expression instance is passed, this is used as-is.
5866        dialect: the dialect used to parse the input expression.
5867        copy: whether or not to copy `expressions` (only applies to Expressions).
5868        **opts: other options to use to parse the input expressions.
5869
5870    Returns:
5871        And: the new condition
5872    """
5873    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:
5876def or_(
5877    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5878) -> Condition:
5879    """
5880    Combine multiple conditions with an OR logical operator.
5881
5882    Example:
5883        >>> or_("x=1", or_("y=1", "z=1")).sql()
5884        'x = 1 OR (y = 1 OR z = 1)'
5885
5886    Args:
5887        *expressions: the SQL code strings to parse.
5888            If an Expression instance is passed, this is used as-is.
5889        dialect: the dialect used to parse the input expression.
5890        copy: whether or not to copy `expressions` (only applies to Expressions).
5891        **opts: other options to use to parse the input expressions.
5892
5893    Returns:
5894        Or: the new condition
5895    """
5896    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:
5899def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5900    """
5901    Wrap a condition with a NOT operator.
5902
5903    Example:
5904        >>> not_("this_suit='black'").sql()
5905        "NOT this_suit = 'black'"
5906
5907    Args:
5908        expression: the SQL code string to parse.
5909            If an Expression instance is passed, this is used as-is.
5910        dialect: the dialect used to parse the input expression.
5911        copy: whether to copy the expression or not.
5912        **opts: other options to use to parse the input expressions.
5913
5914    Returns:
5915        The new condition.
5916    """
5917    this = condition(
5918        expression,
5919        dialect=dialect,
5920        copy=copy,
5921        **opts,
5922    )
5923    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:
5926def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5927    """
5928    Wrap an expression in parentheses.
5929
5930    Example:
5931        >>> paren("5 + 3").sql()
5932        '(5 + 3)'
5933
5934    Args:
5935        expression: the SQL code string to parse.
5936            If an Expression instance is passed, this is used as-is.
5937        copy: whether to copy the expression or not.
5938
5939    Returns:
5940        The wrapped expression.
5941    """
5942    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):
5960def to_identifier(name, quoted=None, copy=True):
5961    """Builds an identifier.
5962
5963    Args:
5964        name: The name to turn into an identifier.
5965        quoted: Whether or not force quote the identifier.
5966        copy: Whether or not to copy name if it's an Identifier.
5967
5968    Returns:
5969        The identifier ast node.
5970    """
5971
5972    if name is None:
5973        return None
5974
5975    if isinstance(name, Identifier):
5976        identifier = maybe_copy(name, copy)
5977    elif isinstance(name, str):
5978        identifier = Identifier(
5979            this=name,
5980            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
5981        )
5982    else:
5983        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
5984    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:
5987def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
5988    """
5989    Parses a given string into an identifier.
5990
5991    Args:
5992        name: The name to parse into an identifier.
5993        dialect: The dialect to parse against.
5994
5995    Returns:
5996        The identifier ast node.
5997    """
5998    try:
5999        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6000    except ParseError:
6001        expression = to_identifier(name)
6002
6003    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:
6009def to_interval(interval: str | Literal) -> Interval:
6010    """Builds an interval expression from a string like '1 day' or '5 months'."""
6011    if isinstance(interval, Literal):
6012        if not interval.is_string:
6013            raise ValueError("Invalid interval string.")
6014
6015        interval = interval.this
6016
6017    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6018
6019    if not interval_parts:
6020        raise ValueError("Invalid interval string.")
6021
6022    return Interval(
6023        this=Literal.string(interval_parts.group(1)),
6024        unit=Var(this=interval_parts.group(2)),
6025    )

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

Build a Column.

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

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], **opts) -> Cast:
6197def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6198    """Cast an expression to a data type.
6199
6200    Example:
6201        >>> cast('x + 1', 'int').sql()
6202        'CAST(x + 1 AS INT)'
6203
6204    Args:
6205        expression: The expression to cast.
6206        to: The datatype to cast to.
6207
6208    Returns:
6209        The new Cast instance.
6210    """
6211    expression = maybe_parse(expression, **opts)
6212    data_type = DataType.build(to, **opts)
6213    expression = Cast(this=expression, to=data_type)
6214    expression.type = data_type
6215    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:
6218def table_(
6219    table: Identifier | str,
6220    db: t.Optional[Identifier | str] = None,
6221    catalog: t.Optional[Identifier | str] = None,
6222    quoted: t.Optional[bool] = None,
6223    alias: t.Optional[Identifier | str] = None,
6224) -> Table:
6225    """Build a Table.
6226
6227    Args:
6228        table: Table name.
6229        db: Database name.
6230        catalog: Catalog name.
6231        quote: Whether to force quotes on the table's identifiers.
6232        alias: Table's alias.
6233
6234    Returns:
6235        The new Table instance.
6236    """
6237    return Table(
6238        this=to_identifier(table, quoted=quoted) if table else None,
6239        db=to_identifier(db, quoted=quoted) if db else None,
6240        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6241        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6242    )

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

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:
6278def var(name: t.Optional[ExpOrStr]) -> Var:
6279    """Build a SQL variable.
6280
6281    Example:
6282        >>> repr(var('x'))
6283        '(VAR this: x)'
6284
6285        >>> repr(var(column('x', table='y')))
6286        '(VAR this: x)'
6287
6288    Args:
6289        name: The name of the var or an expression who's name will become the var.
6290
6291    Returns:
6292        The new variable node.
6293    """
6294    if not name:
6295        raise ValueError("Cannot convert empty name into var.")
6296
6297    if isinstance(name, Expression):
6298        name = name.name
6299    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:
6302def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6303    """Build ALTER TABLE... RENAME... expression
6304
6305    Args:
6306        old_name: The old name of the table
6307        new_name: The new name of the table
6308
6309    Returns:
6310        Alter table expression
6311    """
6312    old_table = to_table(old_name)
6313    new_table = to_table(new_name)
6314    return AlterTable(
6315        this=old_table,
6316        actions=[
6317            RenameTable(this=new_table),
6318        ],
6319    )

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

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:
6409def table_name(table: Table | str, dialect: DialectType = None) -> str:
6410    """Get the full name of a table as a string.
6411
6412    Args:
6413        table: Table expression node or string.
6414        dialect: The dialect to generate the table name for.
6415
6416    Examples:
6417        >>> from sqlglot import exp, parse_one
6418        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6419        'a.b.c'
6420
6421    Returns:
6422        The table name.
6423    """
6424
6425    table = maybe_parse(table, into=Table, dialect=dialect)
6426
6427    if not table:
6428        raise ValueError(f"Cannot parse {table}")
6429
6430    return ".".join(
6431        part.sql(dialect=dialect, identify=True)
6432        if not SAFE_IDENTIFIER_RE.match(part.name)
6433        else part.name
6434        for part in table.parts
6435    )

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

Returns a true Boolean expression.

def false() -> Boolean:
6614def false() -> Boolean:
6615    """
6616    Returns a false Boolean expression.
6617    """
6618    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6621def null() -> Null:
6622    """
6623    Returns a Null expression.
6624    """
6625    return Null()

Returns a Null expression.

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