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 sqlglot.expressions.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 textwrap
  20import typing as t
  21from collections import deque
  22from copy import deepcopy
  23from decimal import Decimal
  24from enum import auto
  25from functools import reduce
  26
  27from sqlglot.errors import ErrorLevel, ParseError
  28from sqlglot.helper import (
  29    AutoName,
  30    camel_to_snake_case,
  31    ensure_collection,
  32    ensure_list,
  33    seq_get,
  34    subclasses,
  35    to_bool,
  36)
  37from sqlglot.tokens import Token, TokenError
  38
  39if t.TYPE_CHECKING:
  40    from typing_extensions import Self
  41
  42    from sqlglot._typing import E, Lit
  43    from sqlglot.dialects.dialect import DialectType
  44
  45    Q = t.TypeVar("Q", bound="Query")
  46    S = t.TypeVar("S", bound="SetOperation")
  47
  48
  49class _Expression(type):
  50    def __new__(cls, clsname, bases, attrs):
  51        klass = super().__new__(cls, clsname, bases, attrs)
  52
  53        # When an Expression class is created, its key is automatically set to be
  54        # the lowercase version of the class' name.
  55        klass.key = clsname.lower()
  56
  57        # This is so that docstrings are not inherited in pdoc
  58        klass.__doc__ = klass.__doc__ or ""
  59
  60        return klass
  61
  62
  63SQLGLOT_META = "sqlglot.meta"
  64SQLGLOT_ANONYMOUS = "sqlglot.anonymous"
  65TABLE_PARTS = ("this", "db", "catalog")
  66COLUMN_PARTS = ("this", "table", "db", "catalog")
  67
  68
  69class Expression(metaclass=_Expression):
  70    """
  71    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  72    context, such as its child expressions, their names (arg keys), and whether a given child expression
  73    is optional or not.
  74
  75    Attributes:
  76        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  77            and representing expressions as strings.
  78        arg_types: determines the arguments (child nodes) supported by an expression. It maps
  79            arg keys to booleans that indicate whether the corresponding args are optional.
  80        parent: a reference to the parent expression (or None, in case of root expressions).
  81        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  82            uses to refer to it.
  83        index: the index of an expression if it is inside of a list argument in its parent.
  84        comments: a list of comments that are associated with a given expression. This is used in
  85            order to preserve comments when transpiling SQL code.
  86        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  87            optimizer, in order to enable some transformations that require type information.
  88        meta: a dictionary that can be used to store useful metadata for a given expression.
  89
  90    Example:
  91        >>> class Foo(Expression):
  92        ...     arg_types = {"this": True, "expression": False}
  93
  94        The above definition informs us that Foo is an Expression that requires an argument called
  95        "this" and may also optionally receive an argument called "expression".
  96
  97    Args:
  98        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
  99    """
 100
 101    key = "expression"
 102    arg_types = {"this": True}
 103    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
 104
 105    def __init__(self, **args: t.Any):
 106        self.args: t.Dict[str, t.Any] = args
 107        self.parent: t.Optional[Expression] = None
 108        self.arg_key: t.Optional[str] = None
 109        self.index: t.Optional[int] = None
 110        self.comments: t.Optional[t.List[str]] = None
 111        self._type: t.Optional[DataType] = None
 112        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 113        self._hash: t.Optional[int] = None
 114
 115        for arg_key, value in self.args.items():
 116            self._set_parent(arg_key, value)
 117
 118    def __eq__(self, other) -> bool:
 119        return type(self) is type(other) and hash(self) == hash(other)
 120
 121    @property
 122    def hashable_args(self) -> t.Any:
 123        return frozenset(
 124            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 125            for k, v in self.args.items()
 126            if not (v is None or v is False or (type(v) is list and not v))
 127        )
 128
 129    def __hash__(self) -> int:
 130        if self._hash is not None:
 131            return self._hash
 132
 133        return hash((self.__class__, self.hashable_args))
 134
 135    @property
 136    def this(self) -> t.Any:
 137        """
 138        Retrieves the argument with key "this".
 139        """
 140        return self.args.get("this")
 141
 142    @property
 143    def expression(self) -> t.Any:
 144        """
 145        Retrieves the argument with key "expression".
 146        """
 147        return self.args.get("expression")
 148
 149    @property
 150    def expressions(self) -> t.List[t.Any]:
 151        """
 152        Retrieves the argument with key "expressions".
 153        """
 154        return self.args.get("expressions") or []
 155
 156    def text(self, key) -> str:
 157        """
 158        Returns a textual representation of the argument corresponding to "key". This can only be used
 159        for args that are strings or leaf Expression instances, such as identifiers and literals.
 160        """
 161        field = self.args.get(key)
 162        if isinstance(field, str):
 163            return field
 164        if isinstance(field, (Identifier, Literal, Var)):
 165            return field.this
 166        if isinstance(field, (Star, Null)):
 167            return field.name
 168        return ""
 169
 170    @property
 171    def is_string(self) -> bool:
 172        """
 173        Checks whether a Literal expression is a string.
 174        """
 175        return isinstance(self, Literal) and self.args["is_string"]
 176
 177    @property
 178    def is_number(self) -> bool:
 179        """
 180        Checks whether a Literal expression is a number.
 181        """
 182        return (isinstance(self, Literal) and not self.args["is_string"]) or (
 183            isinstance(self, Neg) and self.this.is_number
 184        )
 185
 186    def to_py(self) -> t.Any:
 187        """
 188        Returns a Python object equivalent of the SQL node.
 189        """
 190        raise ValueError(f"{self} cannot be converted to a Python object.")
 191
 192    @property
 193    def is_int(self) -> bool:
 194        """
 195        Checks whether an expression is an integer.
 196        """
 197        return self.is_number and isinstance(self.to_py(), int)
 198
 199    @property
 200    def is_star(self) -> bool:
 201        """Checks whether an expression is a star."""
 202        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 203
 204    @property
 205    def alias(self) -> str:
 206        """
 207        Returns the alias of the expression, or an empty string if it's not aliased.
 208        """
 209        if isinstance(self.args.get("alias"), TableAlias):
 210            return self.args["alias"].name
 211        return self.text("alias")
 212
 213    @property
 214    def alias_column_names(self) -> t.List[str]:
 215        table_alias = self.args.get("alias")
 216        if not table_alias:
 217            return []
 218        return [c.name for c in table_alias.args.get("columns") or []]
 219
 220    @property
 221    def name(self) -> str:
 222        return self.text("this")
 223
 224    @property
 225    def alias_or_name(self) -> str:
 226        return self.alias or self.name
 227
 228    @property
 229    def output_name(self) -> str:
 230        """
 231        Name of the output column if this expression is a selection.
 232
 233        If the Expression has no output name, an empty string is returned.
 234
 235        Example:
 236            >>> from sqlglot import parse_one
 237            >>> parse_one("SELECT a").expressions[0].output_name
 238            'a'
 239            >>> parse_one("SELECT b AS c").expressions[0].output_name
 240            'c'
 241            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 242            ''
 243        """
 244        return ""
 245
 246    @property
 247    def type(self) -> t.Optional[DataType]:
 248        return self._type
 249
 250    @type.setter
 251    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 252        if dtype and not isinstance(dtype, DataType):
 253            dtype = DataType.build(dtype)
 254        self._type = dtype  # type: ignore
 255
 256    def is_type(self, *dtypes) -> bool:
 257        return self.type is not None and self.type.is_type(*dtypes)
 258
 259    def is_leaf(self) -> bool:
 260        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 261
 262    @property
 263    def meta(self) -> t.Dict[str, t.Any]:
 264        if self._meta is None:
 265            self._meta = {}
 266        return self._meta
 267
 268    def __deepcopy__(self, memo):
 269        root = self.__class__()
 270        stack = [(self, root)]
 271
 272        while stack:
 273            node, copy = stack.pop()
 274
 275            if node.comments is not None:
 276                copy.comments = deepcopy(node.comments)
 277            if node._type is not None:
 278                copy._type = deepcopy(node._type)
 279            if node._meta is not None:
 280                copy._meta = deepcopy(node._meta)
 281            if node._hash is not None:
 282                copy._hash = node._hash
 283
 284            for k, vs in node.args.items():
 285                if hasattr(vs, "parent"):
 286                    stack.append((vs, vs.__class__()))
 287                    copy.set(k, stack[-1][-1])
 288                elif type(vs) is list:
 289                    copy.args[k] = []
 290
 291                    for v in vs:
 292                        if hasattr(v, "parent"):
 293                            stack.append((v, v.__class__()))
 294                            copy.append(k, stack[-1][-1])
 295                        else:
 296                            copy.append(k, v)
 297                else:
 298                    copy.args[k] = vs
 299
 300        return root
 301
 302    def copy(self) -> Self:
 303        """
 304        Returns a deep copy of the expression.
 305        """
 306        return deepcopy(self)
 307
 308    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
 309        if self.comments is None:
 310            self.comments = []
 311
 312        if comments:
 313            for comment in comments:
 314                _, *meta = comment.split(SQLGLOT_META)
 315                if meta:
 316                    for kv in "".join(meta).split(","):
 317                        k, *v = kv.split("=")
 318                        value = v[0].strip() if v else True
 319                        self.meta[k.strip()] = to_bool(value)
 320
 321                if not prepend:
 322                    self.comments.append(comment)
 323
 324            if prepend:
 325                self.comments = comments + self.comments
 326
 327    def pop_comments(self) -> t.List[str]:
 328        comments = self.comments or []
 329        self.comments = None
 330        return comments
 331
 332    def append(self, arg_key: str, value: t.Any) -> None:
 333        """
 334        Appends value to arg_key if it's a list or sets it as a new list.
 335
 336        Args:
 337            arg_key (str): name of the list expression arg
 338            value (Any): value to append to the list
 339        """
 340        if type(self.args.get(arg_key)) is not list:
 341            self.args[arg_key] = []
 342        self._set_parent(arg_key, value)
 343        values = self.args[arg_key]
 344        if hasattr(value, "parent"):
 345            value.index = len(values)
 346        values.append(value)
 347
 348    def set(
 349        self,
 350        arg_key: str,
 351        value: t.Any,
 352        index: t.Optional[int] = None,
 353        overwrite: bool = True,
 354    ) -> None:
 355        """
 356        Sets arg_key to value.
 357
 358        Args:
 359            arg_key: name of the expression arg.
 360            value: value to set the arg to.
 361            index: if the arg is a list, this specifies what position to add the value in it.
 362            overwrite: assuming an index is given, this determines whether to overwrite the
 363                list entry instead of only inserting a new value (i.e., like list.insert).
 364        """
 365        if index is not None:
 366            expressions = self.args.get(arg_key) or []
 367
 368            if seq_get(expressions, index) is None:
 369                return
 370            if value is None:
 371                expressions.pop(index)
 372                for v in expressions[index:]:
 373                    v.index = v.index - 1
 374                return
 375
 376            if isinstance(value, list):
 377                expressions.pop(index)
 378                expressions[index:index] = value
 379            elif overwrite:
 380                expressions[index] = value
 381            else:
 382                expressions.insert(index, value)
 383
 384            value = expressions
 385        elif value is None:
 386            self.args.pop(arg_key, None)
 387            return
 388
 389        self.args[arg_key] = value
 390        self._set_parent(arg_key, value, index)
 391
 392    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 393        if hasattr(value, "parent"):
 394            value.parent = self
 395            value.arg_key = arg_key
 396            value.index = index
 397        elif type(value) is list:
 398            for index, v in enumerate(value):
 399                if hasattr(v, "parent"):
 400                    v.parent = self
 401                    v.arg_key = arg_key
 402                    v.index = index
 403
 404    @property
 405    def depth(self) -> int:
 406        """
 407        Returns the depth of this tree.
 408        """
 409        if self.parent:
 410            return self.parent.depth + 1
 411        return 0
 412
 413    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
 414        """Yields the key and expression for all arguments, exploding list args."""
 415        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
 416            if type(vs) is list:
 417                for v in reversed(vs) if reverse else vs:  # type: ignore
 418                    if hasattr(v, "parent"):
 419                        yield v
 420            else:
 421                if hasattr(vs, "parent"):
 422                    yield vs
 423
 424    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 425        """
 426        Returns the first node in this tree which matches at least one of
 427        the specified types.
 428
 429        Args:
 430            expression_types: the expression type(s) to match.
 431            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 432
 433        Returns:
 434            The node which matches the criteria or None if no such node was found.
 435        """
 436        return next(self.find_all(*expression_types, bfs=bfs), None)
 437
 438    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 439        """
 440        Returns a generator object which visits all nodes in this tree and only
 441        yields those that match at least one of the specified expression types.
 442
 443        Args:
 444            expression_types: the expression type(s) to match.
 445            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 446
 447        Returns:
 448            The generator object.
 449        """
 450        for expression in self.walk(bfs=bfs):
 451            if isinstance(expression, expression_types):
 452                yield expression
 453
 454    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 455        """
 456        Returns a nearest parent matching expression_types.
 457
 458        Args:
 459            expression_types: the expression type(s) to match.
 460
 461        Returns:
 462            The parent node.
 463        """
 464        ancestor = self.parent
 465        while ancestor and not isinstance(ancestor, expression_types):
 466            ancestor = ancestor.parent
 467        return ancestor  # type: ignore
 468
 469    @property
 470    def parent_select(self) -> t.Optional[Select]:
 471        """
 472        Returns the parent select statement.
 473        """
 474        return self.find_ancestor(Select)
 475
 476    @property
 477    def same_parent(self) -> bool:
 478        """Returns if the parent is the same class as itself."""
 479        return type(self.parent) is self.__class__
 480
 481    def root(self) -> Expression:
 482        """
 483        Returns the root expression of this tree.
 484        """
 485        expression = self
 486        while expression.parent:
 487            expression = expression.parent
 488        return expression
 489
 490    def walk(
 491        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
 492    ) -> t.Iterator[Expression]:
 493        """
 494        Returns a generator object which visits all nodes in this tree.
 495
 496        Args:
 497            bfs: if set to True the BFS traversal order will be applied,
 498                otherwise the DFS traversal will be used instead.
 499            prune: callable that returns True if the generator should stop traversing
 500                this branch of the tree.
 501
 502        Returns:
 503            the generator object.
 504        """
 505        if bfs:
 506            yield from self.bfs(prune=prune)
 507        else:
 508            yield from self.dfs(prune=prune)
 509
 510    def dfs(
 511        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 512    ) -> t.Iterator[Expression]:
 513        """
 514        Returns a generator object which visits all nodes in this tree in
 515        the DFS (Depth-first) order.
 516
 517        Returns:
 518            The generator object.
 519        """
 520        stack = [self]
 521
 522        while stack:
 523            node = stack.pop()
 524
 525            yield node
 526
 527            if prune and prune(node):
 528                continue
 529
 530            for v in node.iter_expressions(reverse=True):
 531                stack.append(v)
 532
 533    def bfs(
 534        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 535    ) -> t.Iterator[Expression]:
 536        """
 537        Returns a generator object which visits all nodes in this tree in
 538        the BFS (Breadth-first) order.
 539
 540        Returns:
 541            The generator object.
 542        """
 543        queue = deque([self])
 544
 545        while queue:
 546            node = queue.popleft()
 547
 548            yield node
 549
 550            if prune and prune(node):
 551                continue
 552
 553            for v in node.iter_expressions():
 554                queue.append(v)
 555
 556    def unnest(self):
 557        """
 558        Returns the first non parenthesis child or self.
 559        """
 560        expression = self
 561        while type(expression) is Paren:
 562            expression = expression.this
 563        return expression
 564
 565    def unalias(self):
 566        """
 567        Returns the inner expression if this is an Alias.
 568        """
 569        if isinstance(self, Alias):
 570            return self.this
 571        return self
 572
 573    def unnest_operands(self):
 574        """
 575        Returns unnested operands as a tuple.
 576        """
 577        return tuple(arg.unnest() for arg in self.iter_expressions())
 578
 579    def flatten(self, unnest=True):
 580        """
 581        Returns a generator which yields child nodes whose parents are the same class.
 582
 583        A AND B AND C -> [A, B, C]
 584        """
 585        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
 586            if type(node) is not self.__class__:
 587                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 588
 589    def __str__(self) -> str:
 590        return self.sql()
 591
 592    def __repr__(self) -> str:
 593        return _to_s(self)
 594
 595    def to_s(self) -> str:
 596        """
 597        Same as __repr__, but includes additional information which can be useful
 598        for debugging, like empty or missing args and the AST nodes' object IDs.
 599        """
 600        return _to_s(self, verbose=True)
 601
 602    def sql(self, dialect: DialectType = None, **opts) -> str:
 603        """
 604        Returns SQL string representation of this tree.
 605
 606        Args:
 607            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 608            opts: other `sqlglot.generator.Generator` options.
 609
 610        Returns:
 611            The SQL string.
 612        """
 613        from sqlglot.dialects import Dialect
 614
 615        return Dialect.get_or_raise(dialect).generate(self, **opts)
 616
 617    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
 618        """
 619        Visits all tree nodes (excluding already transformed ones)
 620        and applies the given transformation function to each node.
 621
 622        Args:
 623            fun: a function which takes a node as an argument and returns a
 624                new transformed node or the same node without modifications. If the function
 625                returns None, then the corresponding node will be removed from the syntax tree.
 626            copy: if set to True a new tree instance is constructed, otherwise the tree is
 627                modified in place.
 628
 629        Returns:
 630            The transformed tree.
 631        """
 632        root = None
 633        new_node = None
 634
 635        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
 636            parent, arg_key, index = node.parent, node.arg_key, node.index
 637            new_node = fun(node, *args, **kwargs)
 638
 639            if not root:
 640                root = new_node
 641            elif parent and arg_key and new_node is not node:
 642                parent.set(arg_key, new_node, index)
 643
 644        assert root
 645        return root.assert_is(Expression)
 646
 647    @t.overload
 648    def replace(self, expression: E) -> E: ...
 649
 650    @t.overload
 651    def replace(self, expression: None) -> None: ...
 652
 653    def replace(self, expression):
 654        """
 655        Swap out this expression with a new expression.
 656
 657        For example::
 658
 659            >>> tree = Select().select("x").from_("tbl")
 660            >>> tree.find(Column).replace(column("y"))
 661            Column(
 662              this=Identifier(this=y, quoted=False))
 663            >>> tree.sql()
 664            'SELECT y FROM tbl'
 665
 666        Args:
 667            expression: new node
 668
 669        Returns:
 670            The new expression or expressions.
 671        """
 672        parent = self.parent
 673
 674        if not parent or parent is expression:
 675            return expression
 676
 677        key = self.arg_key
 678        value = parent.args.get(key)
 679
 680        if type(expression) is list and isinstance(value, Expression):
 681            # We are trying to replace an Expression with a list, so it's assumed that
 682            # the intention was to really replace the parent of this expression.
 683            value.parent.replace(expression)
 684        else:
 685            parent.set(key, expression, self.index)
 686
 687        if expression is not self:
 688            self.parent = None
 689            self.arg_key = None
 690            self.index = None
 691
 692        return expression
 693
 694    def pop(self: E) -> E:
 695        """
 696        Remove this expression from its AST.
 697
 698        Returns:
 699            The popped expression.
 700        """
 701        self.replace(None)
 702        return self
 703
 704    def assert_is(self, type_: t.Type[E]) -> E:
 705        """
 706        Assert that this `Expression` is an instance of `type_`.
 707
 708        If it is NOT an instance of `type_`, this raises an assertion error.
 709        Otherwise, this returns this expression.
 710
 711        Examples:
 712            This is useful for type security in chained expressions:
 713
 714            >>> import sqlglot
 715            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 716            'SELECT x, z FROM y'
 717        """
 718        if not isinstance(self, type_):
 719            raise AssertionError(f"{self} is not {type_}.")
 720        return self
 721
 722    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 723        """
 724        Checks if this expression is valid (e.g. all mandatory args are set).
 725
 726        Args:
 727            args: a sequence of values that were used to instantiate a Func expression. This is used
 728                to check that the provided arguments don't exceed the function argument limit.
 729
 730        Returns:
 731            A list of error messages for all possible errors that were found.
 732        """
 733        errors: t.List[str] = []
 734
 735        for k in self.args:
 736            if k not in self.arg_types:
 737                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 738        for k, mandatory in self.arg_types.items():
 739            v = self.args.get(k)
 740            if mandatory and (v is None or (isinstance(v, list) and not v)):
 741                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 742
 743        if (
 744            args
 745            and isinstance(self, Func)
 746            and len(args) > len(self.arg_types)
 747            and not self.is_var_len_args
 748        ):
 749            errors.append(
 750                f"The number of provided arguments ({len(args)}) is greater than "
 751                f"the maximum number of supported arguments ({len(self.arg_types)})"
 752            )
 753
 754        return errors
 755
 756    def dump(self):
 757        """
 758        Dump this Expression to a JSON-serializable dict.
 759        """
 760        from sqlglot.serde import dump
 761
 762        return dump(self)
 763
 764    @classmethod
 765    def load(cls, obj):
 766        """
 767        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 768        """
 769        from sqlglot.serde import load
 770
 771        return load(obj)
 772
 773    def and_(
 774        self,
 775        *expressions: t.Optional[ExpOrStr],
 776        dialect: DialectType = None,
 777        copy: bool = True,
 778        wrap: bool = True,
 779        **opts,
 780    ) -> Condition:
 781        """
 782        AND this condition with one or multiple expressions.
 783
 784        Example:
 785            >>> condition("x=1").and_("y=1").sql()
 786            'x = 1 AND y = 1'
 787
 788        Args:
 789            *expressions: the SQL code strings to parse.
 790                If an `Expression` instance is passed, it will be used as-is.
 791            dialect: the dialect used to parse the input expression.
 792            copy: whether to copy the involved expressions (only applies to Expressions).
 793            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 794                precedence issues, but can be turned off when the produced AST is too deep and
 795                causes recursion-related issues.
 796            opts: other options to use to parse the input expressions.
 797
 798        Returns:
 799            The new And condition.
 800        """
 801        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 802
 803    def or_(
 804        self,
 805        *expressions: t.Optional[ExpOrStr],
 806        dialect: DialectType = None,
 807        copy: bool = True,
 808        wrap: bool = True,
 809        **opts,
 810    ) -> Condition:
 811        """
 812        OR this condition with one or multiple expressions.
 813
 814        Example:
 815            >>> condition("x=1").or_("y=1").sql()
 816            'x = 1 OR y = 1'
 817
 818        Args:
 819            *expressions: the SQL code strings to parse.
 820                If an `Expression` instance is passed, it will be used as-is.
 821            dialect: the dialect used to parse the input expression.
 822            copy: whether to copy the involved expressions (only applies to Expressions).
 823            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 824                precedence issues, but can be turned off when the produced AST is too deep and
 825                causes recursion-related issues.
 826            opts: other options to use to parse the input expressions.
 827
 828        Returns:
 829            The new Or condition.
 830        """
 831        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 832
 833    def not_(self, copy: bool = True):
 834        """
 835        Wrap this condition with NOT.
 836
 837        Example:
 838            >>> condition("x=1").not_().sql()
 839            'NOT x = 1'
 840
 841        Args:
 842            copy: whether to copy this object.
 843
 844        Returns:
 845            The new Not instance.
 846        """
 847        return not_(self, copy=copy)
 848
 849    def as_(
 850        self,
 851        alias: str | Identifier,
 852        quoted: t.Optional[bool] = None,
 853        dialect: DialectType = None,
 854        copy: bool = True,
 855        **opts,
 856    ) -> Alias:
 857        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 858
 859    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 860        this = self.copy()
 861        other = convert(other, copy=True)
 862        if not isinstance(this, klass) and not isinstance(other, klass):
 863            this = _wrap(this, Binary)
 864            other = _wrap(other, Binary)
 865        if reverse:
 866            return klass(this=other, expression=this)
 867        return klass(this=this, expression=other)
 868
 869    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 870        return Bracket(
 871            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 872        )
 873
 874    def __iter__(self) -> t.Iterator:
 875        if "expressions" in self.arg_types:
 876            return iter(self.args.get("expressions") or [])
 877        # We define this because __getitem__ converts Expression into an iterable, which is
 878        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 879        # See: https://peps.python.org/pep-0234/
 880        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 881
 882    def isin(
 883        self,
 884        *expressions: t.Any,
 885        query: t.Optional[ExpOrStr] = None,
 886        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 887        copy: bool = True,
 888        **opts,
 889    ) -> In:
 890        subquery = maybe_parse(query, copy=copy, **opts) if query else None
 891        if subquery and not isinstance(subquery, Subquery):
 892            subquery = subquery.subquery(copy=False)
 893
 894        return In(
 895            this=maybe_copy(self, copy),
 896            expressions=[convert(e, copy=copy) for e in expressions],
 897            query=subquery,
 898            unnest=(
 899                Unnest(
 900                    expressions=[
 901                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 902                        for e in ensure_list(unnest)
 903                    ]
 904                )
 905                if unnest
 906                else None
 907            ),
 908        )
 909
 910    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 911        return Between(
 912            this=maybe_copy(self, copy),
 913            low=convert(low, copy=copy, **opts),
 914            high=convert(high, copy=copy, **opts),
 915        )
 916
 917    def is_(self, other: ExpOrStr) -> Is:
 918        return self._binop(Is, other)
 919
 920    def like(self, other: ExpOrStr) -> Like:
 921        return self._binop(Like, other)
 922
 923    def ilike(self, other: ExpOrStr) -> ILike:
 924        return self._binop(ILike, other)
 925
 926    def eq(self, other: t.Any) -> EQ:
 927        return self._binop(EQ, other)
 928
 929    def neq(self, other: t.Any) -> NEQ:
 930        return self._binop(NEQ, other)
 931
 932    def rlike(self, other: ExpOrStr) -> RegexpLike:
 933        return self._binop(RegexpLike, other)
 934
 935    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 936        div = self._binop(Div, other)
 937        div.args["typed"] = typed
 938        div.args["safe"] = safe
 939        return div
 940
 941    def asc(self, nulls_first: bool = True) -> Ordered:
 942        return Ordered(this=self.copy(), nulls_first=nulls_first)
 943
 944    def desc(self, nulls_first: bool = False) -> Ordered:
 945        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 946
 947    def __lt__(self, other: t.Any) -> LT:
 948        return self._binop(LT, other)
 949
 950    def __le__(self, other: t.Any) -> LTE:
 951        return self._binop(LTE, other)
 952
 953    def __gt__(self, other: t.Any) -> GT:
 954        return self._binop(GT, other)
 955
 956    def __ge__(self, other: t.Any) -> GTE:
 957        return self._binop(GTE, other)
 958
 959    def __add__(self, other: t.Any) -> Add:
 960        return self._binop(Add, other)
 961
 962    def __radd__(self, other: t.Any) -> Add:
 963        return self._binop(Add, other, reverse=True)
 964
 965    def __sub__(self, other: t.Any) -> Sub:
 966        return self._binop(Sub, other)
 967
 968    def __rsub__(self, other: t.Any) -> Sub:
 969        return self._binop(Sub, other, reverse=True)
 970
 971    def __mul__(self, other: t.Any) -> Mul:
 972        return self._binop(Mul, other)
 973
 974    def __rmul__(self, other: t.Any) -> Mul:
 975        return self._binop(Mul, other, reverse=True)
 976
 977    def __truediv__(self, other: t.Any) -> Div:
 978        return self._binop(Div, other)
 979
 980    def __rtruediv__(self, other: t.Any) -> Div:
 981        return self._binop(Div, other, reverse=True)
 982
 983    def __floordiv__(self, other: t.Any) -> IntDiv:
 984        return self._binop(IntDiv, other)
 985
 986    def __rfloordiv__(self, other: t.Any) -> IntDiv:
 987        return self._binop(IntDiv, other, reverse=True)
 988
 989    def __mod__(self, other: t.Any) -> Mod:
 990        return self._binop(Mod, other)
 991
 992    def __rmod__(self, other: t.Any) -> Mod:
 993        return self._binop(Mod, other, reverse=True)
 994
 995    def __pow__(self, other: t.Any) -> Pow:
 996        return self._binop(Pow, other)
 997
 998    def __rpow__(self, other: t.Any) -> Pow:
 999        return self._binop(Pow, other, reverse=True)
1000
1001    def __and__(self, other: t.Any) -> And:
1002        return self._binop(And, other)
1003
1004    def __rand__(self, other: t.Any) -> And:
1005        return self._binop(And, other, reverse=True)
1006
1007    def __or__(self, other: t.Any) -> Or:
1008        return self._binop(Or, other)
1009
1010    def __ror__(self, other: t.Any) -> Or:
1011        return self._binop(Or, other, reverse=True)
1012
1013    def __neg__(self) -> Neg:
1014        return Neg(this=_wrap(self.copy(), Binary))
1015
1016    def __invert__(self) -> Not:
1017        return not_(self.copy())
1018
1019
1020IntoType = t.Union[
1021    str,
1022    t.Type[Expression],
1023    t.Collection[t.Union[str, t.Type[Expression]]],
1024]
1025ExpOrStr = t.Union[str, Expression]
1026
1027
1028class Condition(Expression):
1029    """Logical conditions like x AND y, or simply x"""
1030
1031
1032class Predicate(Condition):
1033    """Relationships like x = y, x > 1, x >= y."""
1034
1035
1036class DerivedTable(Expression):
1037    @property
1038    def selects(self) -> t.List[Expression]:
1039        return self.this.selects if isinstance(self.this, Query) else []
1040
1041    @property
1042    def named_selects(self) -> t.List[str]:
1043        return [select.output_name for select in self.selects]
1044
1045
1046class Query(Expression):
1047    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1048        """
1049        Returns a `Subquery` that wraps around this query.
1050
1051        Example:
1052            >>> subquery = Select().select("x").from_("tbl").subquery()
1053            >>> Select().select("x").from_(subquery).sql()
1054            'SELECT x FROM (SELECT x FROM tbl)'
1055
1056        Args:
1057            alias: an optional alias for the subquery.
1058            copy: if `False`, modify this expression instance in-place.
1059        """
1060        instance = maybe_copy(self, copy)
1061        if not isinstance(alias, Expression):
1062            alias = TableAlias(this=to_identifier(alias)) if alias else None
1063
1064        return Subquery(this=instance, alias=alias)
1065
1066    def limit(
1067        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1068    ) -> Q:
1069        """
1070        Adds a LIMIT clause to this query.
1071
1072        Example:
1073            >>> select("1").union(select("1")).limit(1).sql()
1074            'SELECT 1 UNION SELECT 1 LIMIT 1'
1075
1076        Args:
1077            expression: the SQL code string to parse.
1078                This can also be an integer.
1079                If a `Limit` instance is passed, it will be used as-is.
1080                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1081            dialect: the dialect used to parse the input expression.
1082            copy: if `False`, modify this expression instance in-place.
1083            opts: other options to use to parse the input expressions.
1084
1085        Returns:
1086            A limited Select expression.
1087        """
1088        return _apply_builder(
1089            expression=expression,
1090            instance=self,
1091            arg="limit",
1092            into=Limit,
1093            prefix="LIMIT",
1094            dialect=dialect,
1095            copy=copy,
1096            into_arg="expression",
1097            **opts,
1098        )
1099
1100    def offset(
1101        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1102    ) -> Q:
1103        """
1104        Set the OFFSET expression.
1105
1106        Example:
1107            >>> Select().from_("tbl").select("x").offset(10).sql()
1108            'SELECT x FROM tbl OFFSET 10'
1109
1110        Args:
1111            expression: the SQL code string to parse.
1112                This can also be an integer.
1113                If a `Offset` instance is passed, this is used as-is.
1114                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1115            dialect: the dialect used to parse the input expression.
1116            copy: if `False`, modify this expression instance in-place.
1117            opts: other options to use to parse the input expressions.
1118
1119        Returns:
1120            The modified Select expression.
1121        """
1122        return _apply_builder(
1123            expression=expression,
1124            instance=self,
1125            arg="offset",
1126            into=Offset,
1127            prefix="OFFSET",
1128            dialect=dialect,
1129            copy=copy,
1130            into_arg="expression",
1131            **opts,
1132        )
1133
1134    def order_by(
1135        self: Q,
1136        *expressions: t.Optional[ExpOrStr],
1137        append: bool = True,
1138        dialect: DialectType = None,
1139        copy: bool = True,
1140        **opts,
1141    ) -> Q:
1142        """
1143        Set the ORDER BY expression.
1144
1145        Example:
1146            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1147            'SELECT x FROM tbl ORDER BY x DESC'
1148
1149        Args:
1150            *expressions: the SQL code strings to parse.
1151                If a `Group` instance is passed, this is used as-is.
1152                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1153            append: if `True`, add to any existing expressions.
1154                Otherwise, this flattens all the `Order` expression into a single expression.
1155            dialect: the dialect used to parse the input expression.
1156            copy: if `False`, modify this expression instance in-place.
1157            opts: other options to use to parse the input expressions.
1158
1159        Returns:
1160            The modified Select expression.
1161        """
1162        return _apply_child_list_builder(
1163            *expressions,
1164            instance=self,
1165            arg="order",
1166            append=append,
1167            copy=copy,
1168            prefix="ORDER BY",
1169            into=Order,
1170            dialect=dialect,
1171            **opts,
1172        )
1173
1174    @property
1175    def ctes(self) -> t.List[CTE]:
1176        """Returns a list of all the CTEs attached to this query."""
1177        with_ = self.args.get("with")
1178        return with_.expressions if with_ else []
1179
1180    @property
1181    def selects(self) -> t.List[Expression]:
1182        """Returns the query's projections."""
1183        raise NotImplementedError("Query objects must implement `selects`")
1184
1185    @property
1186    def named_selects(self) -> t.List[str]:
1187        """Returns the output names of the query's projections."""
1188        raise NotImplementedError("Query objects must implement `named_selects`")
1189
1190    def select(
1191        self: Q,
1192        *expressions: t.Optional[ExpOrStr],
1193        append: bool = True,
1194        dialect: DialectType = None,
1195        copy: bool = True,
1196        **opts,
1197    ) -> Q:
1198        """
1199        Append to or set the SELECT expressions.
1200
1201        Example:
1202            >>> Select().select("x", "y").sql()
1203            'SELECT x, y'
1204
1205        Args:
1206            *expressions: the SQL code strings to parse.
1207                If an `Expression` instance is passed, it will be used as-is.
1208            append: if `True`, add to any existing expressions.
1209                Otherwise, this resets the expressions.
1210            dialect: the dialect used to parse the input expressions.
1211            copy: if `False`, modify this expression instance in-place.
1212            opts: other options to use to parse the input expressions.
1213
1214        Returns:
1215            The modified Query expression.
1216        """
1217        raise NotImplementedError("Query objects must implement `select`")
1218
1219    def with_(
1220        self: Q,
1221        alias: ExpOrStr,
1222        as_: ExpOrStr,
1223        recursive: t.Optional[bool] = None,
1224        materialized: t.Optional[bool] = None,
1225        append: bool = True,
1226        dialect: DialectType = None,
1227        copy: bool = True,
1228        scalar: bool = False,
1229        **opts,
1230    ) -> Q:
1231        """
1232        Append to or set the common table expressions.
1233
1234        Example:
1235            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1236            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1237
1238        Args:
1239            alias: the SQL code string to parse as the table name.
1240                If an `Expression` instance is passed, this is used as-is.
1241            as_: the SQL code string to parse as the table expression.
1242                If an `Expression` instance is passed, it will be used as-is.
1243            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1244            materialized: set the MATERIALIZED part of the expression.
1245            append: if `True`, add to any existing expressions.
1246                Otherwise, this resets the expressions.
1247            dialect: the dialect used to parse the input expression.
1248            copy: if `False`, modify this expression instance in-place.
1249            scalar: if `True`, this is a scalar common table expression.
1250            opts: other options to use to parse the input expressions.
1251
1252        Returns:
1253            The modified expression.
1254        """
1255        return _apply_cte_builder(
1256            self,
1257            alias,
1258            as_,
1259            recursive=recursive,
1260            materialized=materialized,
1261            append=append,
1262            dialect=dialect,
1263            copy=copy,
1264            scalar=scalar,
1265            **opts,
1266        )
1267
1268    def union(
1269        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1270    ) -> Union:
1271        """
1272        Builds a UNION expression.
1273
1274        Example:
1275            >>> import sqlglot
1276            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1277            'SELECT * FROM foo UNION SELECT * FROM bla'
1278
1279        Args:
1280            expressions: the SQL code strings.
1281                If `Expression` instances are passed, they will be used as-is.
1282            distinct: set the DISTINCT flag if and only if this is true.
1283            dialect: the dialect used to parse the input expression.
1284            opts: other options to use to parse the input expressions.
1285
1286        Returns:
1287            The new Union expression.
1288        """
1289        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1290
1291    def intersect(
1292        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1293    ) -> Intersect:
1294        """
1295        Builds an INTERSECT expression.
1296
1297        Example:
1298            >>> import sqlglot
1299            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1300            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1301
1302        Args:
1303            expressions: the SQL code strings.
1304                If `Expression` instances are passed, they will be used as-is.
1305            distinct: set the DISTINCT flag if and only if this is true.
1306            dialect: the dialect used to parse the input expression.
1307            opts: other options to use to parse the input expressions.
1308
1309        Returns:
1310            The new Intersect expression.
1311        """
1312        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1313
1314    def except_(
1315        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1316    ) -> Except:
1317        """
1318        Builds an EXCEPT expression.
1319
1320        Example:
1321            >>> import sqlglot
1322            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1323            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1324
1325        Args:
1326            expressions: the SQL code strings.
1327                If `Expression` instance are passed, they will be used as-is.
1328            distinct: set the DISTINCT flag if and only if this is true.
1329            dialect: the dialect used to parse the input expression.
1330            opts: other options to use to parse the input expressions.
1331
1332        Returns:
1333            The new Except expression.
1334        """
1335        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1336
1337
1338class UDTF(DerivedTable):
1339    @property
1340    def selects(self) -> t.List[Expression]:
1341        alias = self.args.get("alias")
1342        return alias.columns if alias else []
1343
1344
1345class Cache(Expression):
1346    arg_types = {
1347        "this": True,
1348        "lazy": False,
1349        "options": False,
1350        "expression": False,
1351    }
1352
1353
1354class Uncache(Expression):
1355    arg_types = {"this": True, "exists": False}
1356
1357
1358class Refresh(Expression):
1359    pass
1360
1361
1362class DDL(Expression):
1363    @property
1364    def ctes(self) -> t.List[CTE]:
1365        """Returns a list of all the CTEs attached to this statement."""
1366        with_ = self.args.get("with")
1367        return with_.expressions if with_ else []
1368
1369    @property
1370    def selects(self) -> t.List[Expression]:
1371        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1372        return self.expression.selects if isinstance(self.expression, Query) else []
1373
1374    @property
1375    def named_selects(self) -> t.List[str]:
1376        """
1377        If this statement contains a query (e.g. a CTAS), this returns the output
1378        names of the query's projections.
1379        """
1380        return self.expression.named_selects if isinstance(self.expression, Query) else []
1381
1382
1383class DML(Expression):
1384    def returning(
1385        self,
1386        expression: ExpOrStr,
1387        dialect: DialectType = None,
1388        copy: bool = True,
1389        **opts,
1390    ) -> "Self":
1391        """
1392        Set the RETURNING expression. Not supported by all dialects.
1393
1394        Example:
1395            >>> delete("tbl").returning("*", dialect="postgres").sql()
1396            'DELETE FROM tbl RETURNING *'
1397
1398        Args:
1399            expression: the SQL code strings to parse.
1400                If an `Expression` instance is passed, it will be used as-is.
1401            dialect: the dialect used to parse the input expressions.
1402            copy: if `False`, modify this expression instance in-place.
1403            opts: other options to use to parse the input expressions.
1404
1405        Returns:
1406            Delete: the modified expression.
1407        """
1408        return _apply_builder(
1409            expression=expression,
1410            instance=self,
1411            arg="returning",
1412            prefix="RETURNING",
1413            dialect=dialect,
1414            copy=copy,
1415            into=Returning,
1416            **opts,
1417        )
1418
1419
1420class Create(DDL):
1421    arg_types = {
1422        "with": False,
1423        "this": True,
1424        "kind": True,
1425        "expression": False,
1426        "exists": False,
1427        "properties": False,
1428        "replace": False,
1429        "refresh": False,
1430        "unique": False,
1431        "indexes": False,
1432        "no_schema_binding": False,
1433        "begin": False,
1434        "end": False,
1435        "clone": False,
1436        "concurrently": False,
1437        "clustered": False,
1438    }
1439
1440    @property
1441    def kind(self) -> t.Optional[str]:
1442        kind = self.args.get("kind")
1443        return kind and kind.upper()
1444
1445
1446class SequenceProperties(Expression):
1447    arg_types = {
1448        "increment": False,
1449        "minvalue": False,
1450        "maxvalue": False,
1451        "cache": False,
1452        "start": False,
1453        "owned": False,
1454        "options": False,
1455    }
1456
1457
1458class TruncateTable(Expression):
1459    arg_types = {
1460        "expressions": True,
1461        "is_database": False,
1462        "exists": False,
1463        "only": False,
1464        "cluster": False,
1465        "identity": False,
1466        "option": False,
1467        "partition": False,
1468    }
1469
1470
1471# https://docs.snowflake.com/en/sql-reference/sql/create-clone
1472# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_clone_statement
1473# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_copy
1474class Clone(Expression):
1475    arg_types = {"this": True, "shallow": False, "copy": False}
1476
1477
1478class Describe(Expression):
1479    arg_types = {
1480        "this": True,
1481        "style": False,
1482        "kind": False,
1483        "expressions": False,
1484        "partition": False,
1485        "format": False,
1486    }
1487
1488
1489# https://duckdb.org/docs/sql/statements/attach.html#attach
1490class Attach(Expression):
1491    arg_types = {"this": True, "exists": False, "expressions": False}
1492
1493
1494# https://duckdb.org/docs/sql/statements/attach.html#detach
1495class Detach(Expression):
1496    arg_types = {"this": True, "exists": False}
1497
1498
1499# https://duckdb.org/docs/guides/meta/summarize.html
1500class Summarize(Expression):
1501    arg_types = {"this": True, "table": False}
1502
1503
1504class Kill(Expression):
1505    arg_types = {"this": True, "kind": False}
1506
1507
1508class Pragma(Expression):
1509    pass
1510
1511
1512class Declare(Expression):
1513    arg_types = {"expressions": True}
1514
1515
1516class DeclareItem(Expression):
1517    arg_types = {"this": True, "kind": True, "default": False}
1518
1519
1520class Set(Expression):
1521    arg_types = {"expressions": False, "unset": False, "tag": False}
1522
1523
1524class Heredoc(Expression):
1525    arg_types = {"this": True, "tag": False}
1526
1527
1528class SetItem(Expression):
1529    arg_types = {
1530        "this": False,
1531        "expressions": False,
1532        "kind": False,
1533        "collate": False,  # MySQL SET NAMES statement
1534        "global": False,
1535    }
1536
1537
1538class Show(Expression):
1539    arg_types = {
1540        "this": True,
1541        "history": False,
1542        "terse": False,
1543        "target": False,
1544        "offset": False,
1545        "starts_with": False,
1546        "limit": False,
1547        "from": False,
1548        "like": False,
1549        "where": False,
1550        "db": False,
1551        "scope": False,
1552        "scope_kind": False,
1553        "full": False,
1554        "mutex": False,
1555        "query": False,
1556        "channel": False,
1557        "global": False,
1558        "log": False,
1559        "position": False,
1560        "types": False,
1561        "privileges": False,
1562    }
1563
1564
1565class UserDefinedFunction(Expression):
1566    arg_types = {"this": True, "expressions": False, "wrapped": False}
1567
1568
1569class CharacterSet(Expression):
1570    arg_types = {"this": True, "default": False}
1571
1572
1573class RecursiveWithSearch(Expression):
1574    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
1575
1576
1577class With(Expression):
1578    arg_types = {"expressions": True, "recursive": False, "search": False}
1579
1580    @property
1581    def recursive(self) -> bool:
1582        return bool(self.args.get("recursive"))
1583
1584
1585class WithinGroup(Expression):
1586    arg_types = {"this": True, "expression": False}
1587
1588
1589# clickhouse supports scalar ctes
1590# https://clickhouse.com/docs/en/sql-reference/statements/select/with
1591class CTE(DerivedTable):
1592    arg_types = {
1593        "this": True,
1594        "alias": True,
1595        "scalar": False,
1596        "materialized": False,
1597    }
1598
1599
1600class ProjectionDef(Expression):
1601    arg_types = {"this": True, "expression": True}
1602
1603
1604class TableAlias(Expression):
1605    arg_types = {"this": False, "columns": False}
1606
1607    @property
1608    def columns(self):
1609        return self.args.get("columns") or []
1610
1611
1612class BitString(Condition):
1613    pass
1614
1615
1616class HexString(Condition):
1617    arg_types = {"this": True, "is_integer": False}
1618
1619
1620class ByteString(Condition):
1621    pass
1622
1623
1624class RawString(Condition):
1625    pass
1626
1627
1628class UnicodeString(Condition):
1629    arg_types = {"this": True, "escape": False}
1630
1631
1632class Column(Condition):
1633    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1634
1635    @property
1636    def table(self) -> str:
1637        return self.text("table")
1638
1639    @property
1640    def db(self) -> str:
1641        return self.text("db")
1642
1643    @property
1644    def catalog(self) -> str:
1645        return self.text("catalog")
1646
1647    @property
1648    def output_name(self) -> str:
1649        return self.name
1650
1651    @property
1652    def parts(self) -> t.List[Identifier]:
1653        """Return the parts of a column in order catalog, db, table, name."""
1654        return [
1655            t.cast(Identifier, self.args[part])
1656            for part in ("catalog", "db", "table", "this")
1657            if self.args.get(part)
1658        ]
1659
1660    def to_dot(self) -> Dot | Identifier:
1661        """Converts the column into a dot expression."""
1662        parts = self.parts
1663        parent = self.parent
1664
1665        while parent:
1666            if isinstance(parent, Dot):
1667                parts.append(parent.expression)
1668            parent = parent.parent
1669
1670        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
1671
1672
1673class ColumnPosition(Expression):
1674    arg_types = {"this": False, "position": True}
1675
1676
1677class ColumnDef(Expression):
1678    arg_types = {
1679        "this": True,
1680        "kind": False,
1681        "constraints": False,
1682        "exists": False,
1683        "position": False,
1684        "default": False,
1685        "output": False,
1686    }
1687
1688    @property
1689    def constraints(self) -> t.List[ColumnConstraint]:
1690        return self.args.get("constraints") or []
1691
1692    @property
1693    def kind(self) -> t.Optional[DataType]:
1694        return self.args.get("kind")
1695
1696
1697class AlterColumn(Expression):
1698    arg_types = {
1699        "this": True,
1700        "dtype": False,
1701        "collate": False,
1702        "using": False,
1703        "default": False,
1704        "drop": False,
1705        "comment": False,
1706        "allow_null": False,
1707        "visible": False,
1708    }
1709
1710
1711# https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
1712class AlterIndex(Expression):
1713    arg_types = {"this": True, "visible": True}
1714
1715
1716# https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
1717class AlterDistStyle(Expression):
1718    pass
1719
1720
1721class AlterSortKey(Expression):
1722    arg_types = {"this": False, "expressions": False, "compound": False}
1723
1724
1725class AlterSet(Expression):
1726    arg_types = {
1727        "expressions": False,
1728        "option": False,
1729        "tablespace": False,
1730        "access_method": False,
1731        "file_format": False,
1732        "copy_options": False,
1733        "tag": False,
1734        "location": False,
1735        "serde": False,
1736    }
1737
1738
1739class RenameColumn(Expression):
1740    arg_types = {"this": True, "to": True, "exists": False}
1741
1742
1743class AlterRename(Expression):
1744    pass
1745
1746
1747class SwapTable(Expression):
1748    pass
1749
1750
1751class Comment(Expression):
1752    arg_types = {
1753        "this": True,
1754        "kind": True,
1755        "expression": True,
1756        "exists": False,
1757        "materialized": False,
1758    }
1759
1760
1761class Comprehension(Expression):
1762    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
1763
1764
1765# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1766class MergeTreeTTLAction(Expression):
1767    arg_types = {
1768        "this": True,
1769        "delete": False,
1770        "recompress": False,
1771        "to_disk": False,
1772        "to_volume": False,
1773    }
1774
1775
1776# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1777class MergeTreeTTL(Expression):
1778    arg_types = {
1779        "expressions": True,
1780        "where": False,
1781        "group": False,
1782        "aggregates": False,
1783    }
1784
1785
1786# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1787class IndexConstraintOption(Expression):
1788    arg_types = {
1789        "key_block_size": False,
1790        "using": False,
1791        "parser": False,
1792        "comment": False,
1793        "visible": False,
1794        "engine_attr": False,
1795        "secondary_engine_attr": False,
1796    }
1797
1798
1799class ColumnConstraint(Expression):
1800    arg_types = {"this": False, "kind": True}
1801
1802    @property
1803    def kind(self) -> ColumnConstraintKind:
1804        return self.args["kind"]
1805
1806
1807class ColumnConstraintKind(Expression):
1808    pass
1809
1810
1811class AutoIncrementColumnConstraint(ColumnConstraintKind):
1812    pass
1813
1814
1815class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1816    arg_types = {"this": True, "expression": True}
1817
1818
1819class CaseSpecificColumnConstraint(ColumnConstraintKind):
1820    arg_types = {"not_": True}
1821
1822
1823class CharacterSetColumnConstraint(ColumnConstraintKind):
1824    arg_types = {"this": True}
1825
1826
1827class CheckColumnConstraint(ColumnConstraintKind):
1828    arg_types = {"this": True, "enforced": False}
1829
1830
1831class ClusteredColumnConstraint(ColumnConstraintKind):
1832    pass
1833
1834
1835class CollateColumnConstraint(ColumnConstraintKind):
1836    pass
1837
1838
1839class CommentColumnConstraint(ColumnConstraintKind):
1840    pass
1841
1842
1843class CompressColumnConstraint(ColumnConstraintKind):
1844    arg_types = {"this": False}
1845
1846
1847class DateFormatColumnConstraint(ColumnConstraintKind):
1848    arg_types = {"this": True}
1849
1850
1851class DefaultColumnConstraint(ColumnConstraintKind):
1852    pass
1853
1854
1855class EncodeColumnConstraint(ColumnConstraintKind):
1856    pass
1857
1858
1859# https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
1860class ExcludeColumnConstraint(ColumnConstraintKind):
1861    pass
1862
1863
1864class EphemeralColumnConstraint(ColumnConstraintKind):
1865    arg_types = {"this": False}
1866
1867
1868class WithOperator(Expression):
1869    arg_types = {"this": True, "op": True}
1870
1871
1872class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1873    # this: True -> ALWAYS, this: False -> BY DEFAULT
1874    arg_types = {
1875        "this": False,
1876        "expression": False,
1877        "on_null": False,
1878        "start": False,
1879        "increment": False,
1880        "minvalue": False,
1881        "maxvalue": False,
1882        "cycle": False,
1883    }
1884
1885
1886class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1887    arg_types = {"start": False, "hidden": False}
1888
1889
1890# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1891# https://github.com/ClickHouse/ClickHouse/blob/master/src/Parsers/ParserCreateQuery.h#L646
1892class IndexColumnConstraint(ColumnConstraintKind):
1893    arg_types = {
1894        "this": False,
1895        "expressions": False,
1896        "kind": False,
1897        "index_type": False,
1898        "options": False,
1899        "expression": False,  # Clickhouse
1900        "granularity": False,
1901    }
1902
1903
1904class InlineLengthColumnConstraint(ColumnConstraintKind):
1905    pass
1906
1907
1908class NonClusteredColumnConstraint(ColumnConstraintKind):
1909    pass
1910
1911
1912class NotForReplicationColumnConstraint(ColumnConstraintKind):
1913    arg_types = {}
1914
1915
1916# https://docs.snowflake.com/en/sql-reference/sql/create-table
1917class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1918    arg_types = {"this": True, "expressions": False}
1919
1920
1921class NotNullColumnConstraint(ColumnConstraintKind):
1922    arg_types = {"allow_null": False}
1923
1924
1925# https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
1926class OnUpdateColumnConstraint(ColumnConstraintKind):
1927    pass
1928
1929
1930# https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
1931class TransformColumnConstraint(ColumnConstraintKind):
1932    pass
1933
1934
1935class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1936    arg_types = {"desc": False, "options": False}
1937
1938
1939class TitleColumnConstraint(ColumnConstraintKind):
1940    pass
1941
1942
1943class UniqueColumnConstraint(ColumnConstraintKind):
1944    arg_types = {
1945        "this": False,
1946        "index_type": False,
1947        "on_conflict": False,
1948        "nulls": False,
1949        "options": False,
1950    }
1951
1952
1953class UppercaseColumnConstraint(ColumnConstraintKind):
1954    arg_types: t.Dict[str, t.Any] = {}
1955
1956
1957# https://docs.risingwave.com/processing/watermarks#syntax
1958class WatermarkColumnConstraint(Expression):
1959    arg_types = {"this": True, "expression": True}
1960
1961
1962class PathColumnConstraint(ColumnConstraintKind):
1963    pass
1964
1965
1966# https://docs.snowflake.com/en/sql-reference/sql/create-table
1967class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1968    pass
1969
1970
1971# computed column expression
1972# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver16
1973class ComputedColumnConstraint(ColumnConstraintKind):
1974    arg_types = {"this": True, "persisted": False, "not_null": False}
1975
1976
1977class Constraint(Expression):
1978    arg_types = {"this": True, "expressions": True}
1979
1980
1981class Delete(DML):
1982    arg_types = {
1983        "with": False,
1984        "this": False,
1985        "using": False,
1986        "where": False,
1987        "returning": False,
1988        "limit": False,
1989        "tables": False,  # Multiple-Table Syntax (MySQL)
1990        "cluster": False,  # Clickhouse
1991    }
1992
1993    def delete(
1994        self,
1995        table: ExpOrStr,
1996        dialect: DialectType = None,
1997        copy: bool = True,
1998        **opts,
1999    ) -> Delete:
2000        """
2001        Create a DELETE expression or replace the table on an existing DELETE expression.
2002
2003        Example:
2004            >>> delete("tbl").sql()
2005            'DELETE FROM tbl'
2006
2007        Args:
2008            table: the table from which to delete.
2009            dialect: the dialect used to parse the input expression.
2010            copy: if `False`, modify this expression instance in-place.
2011            opts: other options to use to parse the input expressions.
2012
2013        Returns:
2014            Delete: the modified expression.
2015        """
2016        return _apply_builder(
2017            expression=table,
2018            instance=self,
2019            arg="this",
2020            dialect=dialect,
2021            into=Table,
2022            copy=copy,
2023            **opts,
2024        )
2025
2026    def where(
2027        self,
2028        *expressions: t.Optional[ExpOrStr],
2029        append: bool = True,
2030        dialect: DialectType = None,
2031        copy: bool = True,
2032        **opts,
2033    ) -> Delete:
2034        """
2035        Append to or set the WHERE expressions.
2036
2037        Example:
2038            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2039            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2040
2041        Args:
2042            *expressions: the SQL code strings to parse.
2043                If an `Expression` instance is passed, it will be used as-is.
2044                Multiple expressions are combined with an AND operator.
2045            append: if `True`, AND the new expressions to any existing expression.
2046                Otherwise, this resets the expression.
2047            dialect: the dialect used to parse the input expressions.
2048            copy: if `False`, modify this expression instance in-place.
2049            opts: other options to use to parse the input expressions.
2050
2051        Returns:
2052            Delete: the modified expression.
2053        """
2054        return _apply_conjunction_builder(
2055            *expressions,
2056            instance=self,
2057            arg="where",
2058            append=append,
2059            into=Where,
2060            dialect=dialect,
2061            copy=copy,
2062            **opts,
2063        )
2064
2065
2066class Drop(Expression):
2067    arg_types = {
2068        "this": False,
2069        "kind": False,
2070        "expressions": False,
2071        "exists": False,
2072        "temporary": False,
2073        "materialized": False,
2074        "cascade": False,
2075        "constraints": False,
2076        "purge": False,
2077        "cluster": False,
2078        "concurrently": False,
2079    }
2080
2081    @property
2082    def kind(self) -> t.Optional[str]:
2083        kind = self.args.get("kind")
2084        return kind and kind.upper()
2085
2086
2087# https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements
2088class Export(Expression):
2089    arg_types = {"this": True, "connection": False, "options": True}
2090
2091
2092class Filter(Expression):
2093    arg_types = {"this": True, "expression": True}
2094
2095
2096class Check(Expression):
2097    pass
2098
2099
2100class Changes(Expression):
2101    arg_types = {"information": True, "at_before": False, "end": False}
2102
2103
2104# https://docs.snowflake.com/en/sql-reference/constructs/connect-by
2105class Connect(Expression):
2106    arg_types = {"start": False, "connect": True, "nocycle": False}
2107
2108
2109class CopyParameter(Expression):
2110    arg_types = {"this": True, "expression": False, "expressions": False}
2111
2112
2113class Copy(DML):
2114    arg_types = {
2115        "this": True,
2116        "kind": True,
2117        "files": True,
2118        "credentials": False,
2119        "format": False,
2120        "params": False,
2121    }
2122
2123
2124class Credentials(Expression):
2125    arg_types = {
2126        "credentials": False,
2127        "encryption": False,
2128        "storage": False,
2129        "iam_role": False,
2130        "region": False,
2131    }
2132
2133
2134class Prior(Expression):
2135    pass
2136
2137
2138class Directory(Expression):
2139    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2140    arg_types = {"this": True, "local": False, "row_format": False}
2141
2142
2143class ForeignKey(Expression):
2144    arg_types = {
2145        "expressions": False,
2146        "reference": False,
2147        "delete": False,
2148        "update": False,
2149        "options": False,
2150    }
2151
2152
2153class ColumnPrefix(Expression):
2154    arg_types = {"this": True, "expression": True}
2155
2156
2157class PrimaryKey(Expression):
2158    arg_types = {"expressions": True, "options": False}
2159
2160
2161# https://www.postgresql.org/docs/9.1/sql-selectinto.html
2162# https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_INTO.html#r_SELECT_INTO-examples
2163class Into(Expression):
2164    arg_types = {
2165        "this": False,
2166        "temporary": False,
2167        "unlogged": False,
2168        "bulk_collect": False,
2169        "expressions": False,
2170    }
2171
2172
2173class From(Expression):
2174    @property
2175    def name(self) -> str:
2176        return self.this.name
2177
2178    @property
2179    def alias_or_name(self) -> str:
2180        return self.this.alias_or_name
2181
2182
2183class Having(Expression):
2184    pass
2185
2186
2187class Hint(Expression):
2188    arg_types = {"expressions": True}
2189
2190
2191class JoinHint(Expression):
2192    arg_types = {"this": True, "expressions": True}
2193
2194
2195class Identifier(Expression):
2196    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2197
2198    @property
2199    def quoted(self) -> bool:
2200        return bool(self.args.get("quoted"))
2201
2202    @property
2203    def hashable_args(self) -> t.Any:
2204        return (self.this, self.quoted)
2205
2206    @property
2207    def output_name(self) -> str:
2208        return self.name
2209
2210
2211# https://www.postgresql.org/docs/current/indexes-opclass.html
2212class Opclass(Expression):
2213    arg_types = {"this": True, "expression": True}
2214
2215
2216class Index(Expression):
2217    arg_types = {
2218        "this": False,
2219        "table": False,
2220        "unique": False,
2221        "primary": False,
2222        "amp": False,  # teradata
2223        "params": False,
2224    }
2225
2226
2227class IndexParameters(Expression):
2228    arg_types = {
2229        "using": False,
2230        "include": False,
2231        "columns": False,
2232        "with_storage": False,
2233        "partition_by": False,
2234        "tablespace": False,
2235        "where": False,
2236        "on": False,
2237    }
2238
2239
2240class Insert(DDL, DML):
2241    arg_types = {
2242        "hint": False,
2243        "with": False,
2244        "is_function": False,
2245        "this": False,
2246        "expression": False,
2247        "conflict": False,
2248        "returning": False,
2249        "overwrite": False,
2250        "exists": False,
2251        "alternative": False,
2252        "where": False,
2253        "ignore": False,
2254        "by_name": False,
2255        "stored": False,
2256        "partition": False,
2257        "settings": False,
2258        "source": False,
2259    }
2260
2261    def with_(
2262        self,
2263        alias: ExpOrStr,
2264        as_: ExpOrStr,
2265        recursive: t.Optional[bool] = None,
2266        materialized: t.Optional[bool] = None,
2267        append: bool = True,
2268        dialect: DialectType = None,
2269        copy: bool = True,
2270        **opts,
2271    ) -> Insert:
2272        """
2273        Append to or set the common table expressions.
2274
2275        Example:
2276            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2277            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2278
2279        Args:
2280            alias: the SQL code string to parse as the table name.
2281                If an `Expression` instance is passed, this is used as-is.
2282            as_: the SQL code string to parse as the table expression.
2283                If an `Expression` instance is passed, it will be used as-is.
2284            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2285            materialized: set the MATERIALIZED part of the expression.
2286            append: if `True`, add to any existing expressions.
2287                Otherwise, this resets the expressions.
2288            dialect: the dialect used to parse the input expression.
2289            copy: if `False`, modify this expression instance in-place.
2290            opts: other options to use to parse the input expressions.
2291
2292        Returns:
2293            The modified expression.
2294        """
2295        return _apply_cte_builder(
2296            self,
2297            alias,
2298            as_,
2299            recursive=recursive,
2300            materialized=materialized,
2301            append=append,
2302            dialect=dialect,
2303            copy=copy,
2304            **opts,
2305        )
2306
2307
2308class ConditionalInsert(Expression):
2309    arg_types = {"this": True, "expression": False, "else_": False}
2310
2311
2312class MultitableInserts(Expression):
2313    arg_types = {"expressions": True, "kind": True, "source": True}
2314
2315
2316class OnConflict(Expression):
2317    arg_types = {
2318        "duplicate": False,
2319        "expressions": False,
2320        "action": False,
2321        "conflict_keys": False,
2322        "constraint": False,
2323        "where": False,
2324    }
2325
2326
2327class OnCondition(Expression):
2328    arg_types = {"error": False, "empty": False, "null": False}
2329
2330
2331class Returning(Expression):
2332    arg_types = {"expressions": True, "into": False}
2333
2334
2335# https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
2336class Introducer(Expression):
2337    arg_types = {"this": True, "expression": True}
2338
2339
2340# national char, like n'utf8'
2341class National(Expression):
2342    pass
2343
2344
2345class LoadData(Expression):
2346    arg_types = {
2347        "this": True,
2348        "local": False,
2349        "overwrite": False,
2350        "inpath": True,
2351        "partition": False,
2352        "input_format": False,
2353        "serde": False,
2354    }
2355
2356
2357class Partition(Expression):
2358    arg_types = {"expressions": True, "subpartition": False}
2359
2360
2361class PartitionRange(Expression):
2362    arg_types = {"this": True, "expression": True}
2363
2364
2365# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#how-to-set-partition-expression
2366class PartitionId(Expression):
2367    pass
2368
2369
2370class Fetch(Expression):
2371    arg_types = {
2372        "direction": False,
2373        "count": False,
2374        "limit_options": False,
2375    }
2376
2377
2378class Grant(Expression):
2379    arg_types = {
2380        "privileges": True,
2381        "kind": False,
2382        "securable": True,
2383        "principals": True,
2384        "grant_option": False,
2385    }
2386
2387
2388class Group(Expression):
2389    arg_types = {
2390        "expressions": False,
2391        "grouping_sets": False,
2392        "cube": False,
2393        "rollup": False,
2394        "totals": False,
2395        "all": False,
2396    }
2397
2398
2399class Cube(Expression):
2400    arg_types = {"expressions": False}
2401
2402
2403class Rollup(Expression):
2404    arg_types = {"expressions": False}
2405
2406
2407class GroupingSets(Expression):
2408    arg_types = {"expressions": True}
2409
2410
2411class Lambda(Expression):
2412    arg_types = {"this": True, "expressions": True}
2413
2414
2415class Limit(Expression):
2416    arg_types = {
2417        "this": False,
2418        "expression": True,
2419        "offset": False,
2420        "limit_options": False,
2421        "expressions": False,
2422    }
2423
2424
2425class LimitOptions(Expression):
2426    arg_types = {
2427        "percent": False,
2428        "rows": False,
2429        "with_ties": False,
2430    }
2431
2432
2433class Literal(Condition):
2434    arg_types = {"this": True, "is_string": True}
2435
2436    @property
2437    def hashable_args(self) -> t.Any:
2438        return (self.this, self.args.get("is_string"))
2439
2440    @classmethod
2441    def number(cls, number) -> Literal:
2442        return cls(this=str(number), is_string=False)
2443
2444    @classmethod
2445    def string(cls, string) -> Literal:
2446        return cls(this=str(string), is_string=True)
2447
2448    @property
2449    def output_name(self) -> str:
2450        return self.name
2451
2452    def to_py(self) -> int | str | Decimal:
2453        if self.is_number:
2454            try:
2455                return int(self.this)
2456            except ValueError:
2457                return Decimal(self.this)
2458        return self.this
2459
2460
2461class Join(Expression):
2462    arg_types = {
2463        "this": True,
2464        "on": False,
2465        "side": False,
2466        "kind": False,
2467        "using": False,
2468        "method": False,
2469        "global": False,
2470        "hint": False,
2471        "match_condition": False,  # Snowflake
2472        "expressions": False,
2473    }
2474
2475    @property
2476    def method(self) -> str:
2477        return self.text("method").upper()
2478
2479    @property
2480    def kind(self) -> str:
2481        return self.text("kind").upper()
2482
2483    @property
2484    def side(self) -> str:
2485        return self.text("side").upper()
2486
2487    @property
2488    def hint(self) -> str:
2489        return self.text("hint").upper()
2490
2491    @property
2492    def alias_or_name(self) -> str:
2493        return self.this.alias_or_name
2494
2495    @property
2496    def is_semi_or_anti_join(self) -> bool:
2497        return self.kind in ("SEMI", "ANTI")
2498
2499    def on(
2500        self,
2501        *expressions: t.Optional[ExpOrStr],
2502        append: bool = True,
2503        dialect: DialectType = None,
2504        copy: bool = True,
2505        **opts,
2506    ) -> Join:
2507        """
2508        Append to or set the ON expressions.
2509
2510        Example:
2511            >>> import sqlglot
2512            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2513            'JOIN x ON y = 1'
2514
2515        Args:
2516            *expressions: the SQL code strings to parse.
2517                If an `Expression` instance is passed, it will be used as-is.
2518                Multiple expressions are combined with an AND operator.
2519            append: if `True`, AND the new expressions to any existing expression.
2520                Otherwise, this resets the expression.
2521            dialect: the dialect used to parse the input expressions.
2522            copy: if `False`, modify this expression instance in-place.
2523            opts: other options to use to parse the input expressions.
2524
2525        Returns:
2526            The modified Join expression.
2527        """
2528        join = _apply_conjunction_builder(
2529            *expressions,
2530            instance=self,
2531            arg="on",
2532            append=append,
2533            dialect=dialect,
2534            copy=copy,
2535            **opts,
2536        )
2537
2538        if join.kind == "CROSS":
2539            join.set("kind", None)
2540
2541        return join
2542
2543    def using(
2544        self,
2545        *expressions: t.Optional[ExpOrStr],
2546        append: bool = True,
2547        dialect: DialectType = None,
2548        copy: bool = True,
2549        **opts,
2550    ) -> Join:
2551        """
2552        Append to or set the USING expressions.
2553
2554        Example:
2555            >>> import sqlglot
2556            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2557            'JOIN x USING (foo, bla)'
2558
2559        Args:
2560            *expressions: the SQL code strings to parse.
2561                If an `Expression` instance is passed, it will be used as-is.
2562            append: if `True`, concatenate the new expressions to the existing "using" list.
2563                Otherwise, this resets the expression.
2564            dialect: the dialect used to parse the input expressions.
2565            copy: if `False`, modify this expression instance in-place.
2566            opts: other options to use to parse the input expressions.
2567
2568        Returns:
2569            The modified Join expression.
2570        """
2571        join = _apply_list_builder(
2572            *expressions,
2573            instance=self,
2574            arg="using",
2575            append=append,
2576            dialect=dialect,
2577            copy=copy,
2578            **opts,
2579        )
2580
2581        if join.kind == "CROSS":
2582            join.set("kind", None)
2583
2584        return join
2585
2586
2587class Lateral(UDTF):
2588    arg_types = {
2589        "this": True,
2590        "view": False,
2591        "outer": False,
2592        "alias": False,
2593        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2594        "ordinality": False,
2595    }
2596
2597
2598# https://docs.snowflake.com/sql-reference/literals-table
2599# https://docs.snowflake.com/en/sql-reference/functions-table#using-a-table-function
2600class TableFromRows(UDTF):
2601    arg_types = {
2602        "this": True,
2603        "alias": False,
2604        "joins": False,
2605        "pivots": False,
2606        "sample": False,
2607    }
2608
2609
2610class MatchRecognizeMeasure(Expression):
2611    arg_types = {
2612        "this": True,
2613        "window_frame": False,
2614    }
2615
2616
2617class MatchRecognize(Expression):
2618    arg_types = {
2619        "partition_by": False,
2620        "order": False,
2621        "measures": False,
2622        "rows": False,
2623        "after": False,
2624        "pattern": False,
2625        "define": False,
2626        "alias": False,
2627    }
2628
2629
2630# Clickhouse FROM FINAL modifier
2631# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
2632class Final(Expression):
2633    pass
2634
2635
2636class Offset(Expression):
2637    arg_types = {"this": False, "expression": True, "expressions": False}
2638
2639
2640class Order(Expression):
2641    arg_types = {"this": False, "expressions": True, "siblings": False}
2642
2643
2644# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
2645class WithFill(Expression):
2646    arg_types = {
2647        "from": False,
2648        "to": False,
2649        "step": False,
2650        "interpolate": False,
2651    }
2652
2653
2654# hive specific sorts
2655# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
2656class Cluster(Order):
2657    pass
2658
2659
2660class Distribute(Order):
2661    pass
2662
2663
2664class Sort(Order):
2665    pass
2666
2667
2668class Ordered(Expression):
2669    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2670
2671    @property
2672    def name(self) -> str:
2673        return self.this.name
2674
2675
2676class Property(Expression):
2677    arg_types = {"this": True, "value": True}
2678
2679
2680class GrantPrivilege(Expression):
2681    arg_types = {"this": True, "expressions": False}
2682
2683
2684class GrantPrincipal(Expression):
2685    arg_types = {"this": True, "kind": False}
2686
2687
2688class AllowedValuesProperty(Expression):
2689    arg_types = {"expressions": True}
2690
2691
2692class AlgorithmProperty(Property):
2693    arg_types = {"this": True}
2694
2695
2696class AutoIncrementProperty(Property):
2697    arg_types = {"this": True}
2698
2699
2700# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2701class AutoRefreshProperty(Property):
2702    arg_types = {"this": True}
2703
2704
2705class BackupProperty(Property):
2706    arg_types = {"this": True}
2707
2708
2709class BlockCompressionProperty(Property):
2710    arg_types = {
2711        "autotemp": False,
2712        "always": False,
2713        "default": False,
2714        "manual": False,
2715        "never": False,
2716    }
2717
2718
2719class CharacterSetProperty(Property):
2720    arg_types = {"this": True, "default": True}
2721
2722
2723class ChecksumProperty(Property):
2724    arg_types = {"on": False, "default": False}
2725
2726
2727class CollateProperty(Property):
2728    arg_types = {"this": True, "default": False}
2729
2730
2731class CopyGrantsProperty(Property):
2732    arg_types = {}
2733
2734
2735class DataBlocksizeProperty(Property):
2736    arg_types = {
2737        "size": False,
2738        "units": False,
2739        "minimum": False,
2740        "maximum": False,
2741        "default": False,
2742    }
2743
2744
2745class DataDeletionProperty(Property):
2746    arg_types = {"on": True, "filter_col": False, "retention_period": False}
2747
2748
2749class DefinerProperty(Property):
2750    arg_types = {"this": True}
2751
2752
2753class DistKeyProperty(Property):
2754    arg_types = {"this": True}
2755
2756
2757# https://docs.starrocks.io/docs/sql-reference/sql-statements/data-definition/CREATE_TABLE/#distribution_desc
2758# https://doris.apache.org/docs/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE?_highlight=create&_highlight=table#distribution_desc
2759class DistributedByProperty(Property):
2760    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
2761
2762
2763class DistStyleProperty(Property):
2764    arg_types = {"this": True}
2765
2766
2767class DuplicateKeyProperty(Property):
2768    arg_types = {"expressions": True}
2769
2770
2771class EngineProperty(Property):
2772    arg_types = {"this": True}
2773
2774
2775class HeapProperty(Property):
2776    arg_types = {}
2777
2778
2779class ToTableProperty(Property):
2780    arg_types = {"this": True}
2781
2782
2783class ExecuteAsProperty(Property):
2784    arg_types = {"this": True}
2785
2786
2787class ExternalProperty(Property):
2788    arg_types = {"this": False}
2789
2790
2791class FallbackProperty(Property):
2792    arg_types = {"no": True, "protection": False}
2793
2794
2795class FileFormatProperty(Property):
2796    arg_types = {"this": False, "expressions": False}
2797
2798
2799class CredentialsProperty(Property):
2800    arg_types = {"expressions": True}
2801
2802
2803class FreespaceProperty(Property):
2804    arg_types = {"this": True, "percent": False}
2805
2806
2807class GlobalProperty(Property):
2808    arg_types = {}
2809
2810
2811class IcebergProperty(Property):
2812    arg_types = {}
2813
2814
2815class InheritsProperty(Property):
2816    arg_types = {"expressions": True}
2817
2818
2819class InputModelProperty(Property):
2820    arg_types = {"this": True}
2821
2822
2823class OutputModelProperty(Property):
2824    arg_types = {"this": True}
2825
2826
2827class IsolatedLoadingProperty(Property):
2828    arg_types = {"no": False, "concurrent": False, "target": False}
2829
2830
2831class JournalProperty(Property):
2832    arg_types = {
2833        "no": False,
2834        "dual": False,
2835        "before": False,
2836        "local": False,
2837        "after": False,
2838    }
2839
2840
2841class LanguageProperty(Property):
2842    arg_types = {"this": True}
2843
2844
2845# spark ddl
2846class ClusteredByProperty(Property):
2847    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2848
2849
2850class DictProperty(Property):
2851    arg_types = {"this": True, "kind": True, "settings": False}
2852
2853
2854class DictSubProperty(Property):
2855    pass
2856
2857
2858class DictRange(Property):
2859    arg_types = {"this": True, "min": True, "max": True}
2860
2861
2862class DynamicProperty(Property):
2863    arg_types = {}
2864
2865
2866# Clickhouse CREATE ... ON CLUSTER modifier
2867# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2868class OnCluster(Property):
2869    arg_types = {"this": True}
2870
2871
2872# Clickhouse EMPTY table "property"
2873class EmptyProperty(Property):
2874    arg_types = {}
2875
2876
2877class LikeProperty(Property):
2878    arg_types = {"this": True, "expressions": False}
2879
2880
2881class LocationProperty(Property):
2882    arg_types = {"this": True}
2883
2884
2885class LockProperty(Property):
2886    arg_types = {"this": True}
2887
2888
2889class LockingProperty(Property):
2890    arg_types = {
2891        "this": False,
2892        "kind": True,
2893        "for_or_in": False,
2894        "lock_type": True,
2895        "override": False,
2896    }
2897
2898
2899class LogProperty(Property):
2900    arg_types = {"no": True}
2901
2902
2903class MaterializedProperty(Property):
2904    arg_types = {"this": False}
2905
2906
2907class MergeBlockRatioProperty(Property):
2908    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2909
2910
2911class NoPrimaryIndexProperty(Property):
2912    arg_types = {}
2913
2914
2915class OnProperty(Property):
2916    arg_types = {"this": True}
2917
2918
2919class OnCommitProperty(Property):
2920    arg_types = {"delete": False}
2921
2922
2923class PartitionedByProperty(Property):
2924    arg_types = {"this": True}
2925
2926
2927class PartitionedByBucket(Property):
2928    arg_types = {"this": True, "expression": True}
2929
2930
2931class PartitionByTruncate(Property):
2932    arg_types = {"this": True, "expression": True}
2933
2934
2935# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2936class PartitionByRangeProperty(Property):
2937    arg_types = {"partition_expressions": True, "create_expressions": True}
2938
2939
2940# https://docs.starrocks.io/docs/table_design/data_distribution/#range-partitioning
2941class PartitionByRangePropertyDynamic(Expression):
2942    arg_types = {"this": False, "start": True, "end": True, "every": True}
2943
2944
2945# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2946class UniqueKeyProperty(Property):
2947    arg_types = {"expressions": True}
2948
2949
2950# https://www.postgresql.org/docs/current/sql-createtable.html
2951class PartitionBoundSpec(Expression):
2952    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2953    arg_types = {
2954        "this": False,
2955        "expression": False,
2956        "from_expressions": False,
2957        "to_expressions": False,
2958    }
2959
2960
2961class PartitionedOfProperty(Property):
2962    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2963    arg_types = {"this": True, "expression": True}
2964
2965
2966class StreamingTableProperty(Property):
2967    arg_types = {}
2968
2969
2970class RemoteWithConnectionModelProperty(Property):
2971    arg_types = {"this": True}
2972
2973
2974class ReturnsProperty(Property):
2975    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
2976
2977
2978class StrictProperty(Property):
2979    arg_types = {}
2980
2981
2982class RowFormatProperty(Property):
2983    arg_types = {"this": True}
2984
2985
2986class RowFormatDelimitedProperty(Property):
2987    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2988    arg_types = {
2989        "fields": False,
2990        "escaped": False,
2991        "collection_items": False,
2992        "map_keys": False,
2993        "lines": False,
2994        "null": False,
2995        "serde": False,
2996    }
2997
2998
2999class RowFormatSerdeProperty(Property):
3000    arg_types = {"this": True, "serde_properties": False}
3001
3002
3003# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
3004class QueryTransform(Expression):
3005    arg_types = {
3006        "expressions": True,
3007        "command_script": True,
3008        "schema": False,
3009        "row_format_before": False,
3010        "record_writer": False,
3011        "row_format_after": False,
3012        "record_reader": False,
3013    }
3014
3015
3016class SampleProperty(Property):
3017    arg_types = {"this": True}
3018
3019
3020# https://prestodb.io/docs/current/sql/create-view.html#synopsis
3021class SecurityProperty(Property):
3022    arg_types = {"this": True}
3023
3024
3025class SchemaCommentProperty(Property):
3026    arg_types = {"this": True}
3027
3028
3029class SerdeProperties(Property):
3030    arg_types = {"expressions": True, "with": False}
3031
3032
3033class SetProperty(Property):
3034    arg_types = {"multi": True}
3035
3036
3037class SharingProperty(Property):
3038    arg_types = {"this": False}
3039
3040
3041class SetConfigProperty(Property):
3042    arg_types = {"this": True}
3043
3044
3045class SettingsProperty(Property):
3046    arg_types = {"expressions": True}
3047
3048
3049class SortKeyProperty(Property):
3050    arg_types = {"this": True, "compound": False}
3051
3052
3053class SqlReadWriteProperty(Property):
3054    arg_types = {"this": True}
3055
3056
3057class SqlSecurityProperty(Property):
3058    arg_types = {"definer": True}
3059
3060
3061class StabilityProperty(Property):
3062    arg_types = {"this": True}
3063
3064
3065class StorageHandlerProperty(Property):
3066    arg_types = {"this": True}
3067
3068
3069class TemporaryProperty(Property):
3070    arg_types = {"this": False}
3071
3072
3073class SecureProperty(Property):
3074    arg_types = {}
3075
3076
3077# https://docs.snowflake.com/en/sql-reference/sql/create-table
3078class Tags(ColumnConstraintKind, Property):
3079    arg_types = {"expressions": True}
3080
3081
3082class TransformModelProperty(Property):
3083    arg_types = {"expressions": True}
3084
3085
3086class TransientProperty(Property):
3087    arg_types = {"this": False}
3088
3089
3090class UnloggedProperty(Property):
3091    arg_types = {}
3092
3093
3094# https://docs.snowflake.com/en/sql-reference/sql/create-table#create-table-using-template
3095class UsingTemplateProperty(Property):
3096    arg_types = {"this": True}
3097
3098
3099# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
3100class ViewAttributeProperty(Property):
3101    arg_types = {"this": True}
3102
3103
3104class VolatileProperty(Property):
3105    arg_types = {"this": False}
3106
3107
3108class WithDataProperty(Property):
3109    arg_types = {"no": True, "statistics": False}
3110
3111
3112class WithJournalTableProperty(Property):
3113    arg_types = {"this": True}
3114
3115
3116class WithSchemaBindingProperty(Property):
3117    arg_types = {"this": True}
3118
3119
3120class WithSystemVersioningProperty(Property):
3121    arg_types = {
3122        "on": False,
3123        "this": False,
3124        "data_consistency": False,
3125        "retention_period": False,
3126        "with": True,
3127    }
3128
3129
3130class WithProcedureOptions(Property):
3131    arg_types = {"expressions": True}
3132
3133
3134class EncodeProperty(Property):
3135    arg_types = {"this": True, "properties": False, "key": False}
3136
3137
3138class IncludeProperty(Property):
3139    arg_types = {"this": True, "alias": False, "column_def": False}
3140
3141
3142class ForceProperty(Property):
3143    arg_types = {}
3144
3145
3146class Properties(Expression):
3147    arg_types = {"expressions": True}
3148
3149    NAME_TO_PROPERTY = {
3150        "ALGORITHM": AlgorithmProperty,
3151        "AUTO_INCREMENT": AutoIncrementProperty,
3152        "CHARACTER SET": CharacterSetProperty,
3153        "CLUSTERED_BY": ClusteredByProperty,
3154        "COLLATE": CollateProperty,
3155        "COMMENT": SchemaCommentProperty,
3156        "CREDENTIALS": CredentialsProperty,
3157        "DEFINER": DefinerProperty,
3158        "DISTKEY": DistKeyProperty,
3159        "DISTRIBUTED_BY": DistributedByProperty,
3160        "DISTSTYLE": DistStyleProperty,
3161        "ENGINE": EngineProperty,
3162        "EXECUTE AS": ExecuteAsProperty,
3163        "FORMAT": FileFormatProperty,
3164        "LANGUAGE": LanguageProperty,
3165        "LOCATION": LocationProperty,
3166        "LOCK": LockProperty,
3167        "PARTITIONED_BY": PartitionedByProperty,
3168        "RETURNS": ReturnsProperty,
3169        "ROW_FORMAT": RowFormatProperty,
3170        "SORTKEY": SortKeyProperty,
3171        "ENCODE": EncodeProperty,
3172        "INCLUDE": IncludeProperty,
3173    }
3174
3175    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3176
3177    # CREATE property locations
3178    # Form: schema specified
3179    #   create [POST_CREATE]
3180    #     table a [POST_NAME]
3181    #     (b int) [POST_SCHEMA]
3182    #     with ([POST_WITH])
3183    #     index (b) [POST_INDEX]
3184    #
3185    # Form: alias selection
3186    #   create [POST_CREATE]
3187    #     table a [POST_NAME]
3188    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3189    #     index (c) [POST_INDEX]
3190    class Location(AutoName):
3191        POST_CREATE = auto()
3192        POST_NAME = auto()
3193        POST_SCHEMA = auto()
3194        POST_WITH = auto()
3195        POST_ALIAS = auto()
3196        POST_EXPRESSION = auto()
3197        POST_INDEX = auto()
3198        UNSUPPORTED = auto()
3199
3200    @classmethod
3201    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3202        expressions = []
3203        for key, value in properties_dict.items():
3204            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3205            if property_cls:
3206                expressions.append(property_cls(this=convert(value)))
3207            else:
3208                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3209
3210        return cls(expressions=expressions)
3211
3212
3213class Qualify(Expression):
3214    pass
3215
3216
3217class InputOutputFormat(Expression):
3218    arg_types = {"input_format": False, "output_format": False}
3219
3220
3221# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
3222class Return(Expression):
3223    pass
3224
3225
3226class Reference(Expression):
3227    arg_types = {"this": True, "expressions": False, "options": False}
3228
3229
3230class Tuple(Expression):
3231    arg_types = {"expressions": False}
3232
3233    def isin(
3234        self,
3235        *expressions: t.Any,
3236        query: t.Optional[ExpOrStr] = None,
3237        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3238        copy: bool = True,
3239        **opts,
3240    ) -> In:
3241        return In(
3242            this=maybe_copy(self, copy),
3243            expressions=[convert(e, copy=copy) for e in expressions],
3244            query=maybe_parse(query, copy=copy, **opts) if query else None,
3245            unnest=(
3246                Unnest(
3247                    expressions=[
3248                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3249                        for e in ensure_list(unnest)
3250                    ]
3251                )
3252                if unnest
3253                else None
3254            ),
3255        )
3256
3257
3258QUERY_MODIFIERS = {
3259    "match": False,
3260    "laterals": False,
3261    "joins": False,
3262    "connect": False,
3263    "pivots": False,
3264    "prewhere": False,
3265    "where": False,
3266    "group": False,
3267    "having": False,
3268    "qualify": False,
3269    "windows": False,
3270    "distribute": False,
3271    "sort": False,
3272    "cluster": False,
3273    "order": False,
3274    "limit": False,
3275    "offset": False,
3276    "locks": False,
3277    "sample": False,
3278    "settings": False,
3279    "format": False,
3280    "options": False,
3281}
3282
3283
3284# https://learn.microsoft.com/en-us/sql/t-sql/queries/option-clause-transact-sql?view=sql-server-ver16
3285# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-ver16
3286class QueryOption(Expression):
3287    arg_types = {"this": True, "expression": False}
3288
3289
3290# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
3291class WithTableHint(Expression):
3292    arg_types = {"expressions": True}
3293
3294
3295# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
3296class IndexTableHint(Expression):
3297    arg_types = {"this": True, "expressions": False, "target": False}
3298
3299
3300# https://docs.snowflake.com/en/sql-reference/constructs/at-before
3301class HistoricalData(Expression):
3302    arg_types = {"this": True, "kind": True, "expression": True}
3303
3304
3305# https://docs.snowflake.com/en/sql-reference/sql/put
3306class Put(Expression):
3307    arg_types = {"this": True, "target": True, "properties": False}
3308
3309
3310class Table(Expression):
3311    arg_types = {
3312        "this": False,
3313        "alias": False,
3314        "db": False,
3315        "catalog": False,
3316        "laterals": False,
3317        "joins": False,
3318        "pivots": False,
3319        "hints": False,
3320        "system_time": False,
3321        "version": False,
3322        "format": False,
3323        "pattern": False,
3324        "ordinality": False,
3325        "when": False,
3326        "only": False,
3327        "partition": False,
3328        "changes": False,
3329        "rows_from": False,
3330        "sample": False,
3331    }
3332
3333    @property
3334    def name(self) -> str:
3335        if not self.this or isinstance(self.this, Func):
3336            return ""
3337        return self.this.name
3338
3339    @property
3340    def db(self) -> str:
3341        return self.text("db")
3342
3343    @property
3344    def catalog(self) -> str:
3345        return self.text("catalog")
3346
3347    @property
3348    def selects(self) -> t.List[Expression]:
3349        return []
3350
3351    @property
3352    def named_selects(self) -> t.List[str]:
3353        return []
3354
3355    @property
3356    def parts(self) -> t.List[Expression]:
3357        """Return the parts of a table in order catalog, db, table."""
3358        parts: t.List[Expression] = []
3359
3360        for arg in ("catalog", "db", "this"):
3361            part = self.args.get(arg)
3362
3363            if isinstance(part, Dot):
3364                parts.extend(part.flatten())
3365            elif isinstance(part, Expression):
3366                parts.append(part)
3367
3368        return parts
3369
3370    def to_column(self, copy: bool = True) -> Expression:
3371        parts = self.parts
3372        last_part = parts[-1]
3373
3374        if isinstance(last_part, Identifier):
3375            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3376        else:
3377            # This branch will be reached if a function or array is wrapped in a `Table`
3378            col = last_part
3379
3380        alias = self.args.get("alias")
3381        if alias:
3382            col = alias_(col, alias.this, copy=copy)
3383
3384        return col
3385
3386
3387class SetOperation(Query):
3388    arg_types = {
3389        "with": False,
3390        "this": True,
3391        "expression": True,
3392        "distinct": False,
3393        "by_name": False,
3394        "side": False,
3395        "kind": False,
3396        "on": False,
3397        **QUERY_MODIFIERS,
3398    }
3399
3400    def select(
3401        self: S,
3402        *expressions: t.Optional[ExpOrStr],
3403        append: bool = True,
3404        dialect: DialectType = None,
3405        copy: bool = True,
3406        **opts,
3407    ) -> S:
3408        this = maybe_copy(self, copy)
3409        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3410        this.expression.unnest().select(
3411            *expressions, append=append, dialect=dialect, copy=False, **opts
3412        )
3413        return this
3414
3415    @property
3416    def named_selects(self) -> t.List[str]:
3417        return self.this.unnest().named_selects
3418
3419    @property
3420    def is_star(self) -> bool:
3421        return self.this.is_star or self.expression.is_star
3422
3423    @property
3424    def selects(self) -> t.List[Expression]:
3425        return self.this.unnest().selects
3426
3427    @property
3428    def left(self) -> Query:
3429        return self.this
3430
3431    @property
3432    def right(self) -> Query:
3433        return self.expression
3434
3435    @property
3436    def kind(self) -> str:
3437        return self.text("kind").upper()
3438
3439    @property
3440    def side(self) -> str:
3441        return self.text("side").upper()
3442
3443
3444class Union(SetOperation):
3445    pass
3446
3447
3448class Except(SetOperation):
3449    pass
3450
3451
3452class Intersect(SetOperation):
3453    pass
3454
3455
3456class Update(DML):
3457    arg_types = {
3458        "with": False,
3459        "this": False,
3460        "expressions": True,
3461        "from": False,
3462        "where": False,
3463        "returning": False,
3464        "order": False,
3465        "limit": False,
3466    }
3467
3468    def table(
3469        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3470    ) -> Update:
3471        """
3472        Set the table to update.
3473
3474        Example:
3475            >>> Update().table("my_table").set_("x = 1").sql()
3476            'UPDATE my_table SET x = 1'
3477
3478        Args:
3479            expression : the SQL code strings to parse.
3480                If a `Table` instance is passed, this is used as-is.
3481                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3482            dialect: the dialect used to parse the input expression.
3483            copy: if `False`, modify this expression instance in-place.
3484            opts: other options to use to parse the input expressions.
3485
3486        Returns:
3487            The modified Update expression.
3488        """
3489        return _apply_builder(
3490            expression=expression,
3491            instance=self,
3492            arg="this",
3493            into=Table,
3494            prefix=None,
3495            dialect=dialect,
3496            copy=copy,
3497            **opts,
3498        )
3499
3500    def set_(
3501        self,
3502        *expressions: ExpOrStr,
3503        append: bool = True,
3504        dialect: DialectType = None,
3505        copy: bool = True,
3506        **opts,
3507    ) -> Update:
3508        """
3509        Append to or set the SET expressions.
3510
3511        Example:
3512            >>> Update().table("my_table").set_("x = 1").sql()
3513            'UPDATE my_table SET x = 1'
3514
3515        Args:
3516            *expressions: the SQL code strings to parse.
3517                If `Expression` instance(s) are passed, they will be used as-is.
3518                Multiple expressions are combined with a comma.
3519            append: if `True`, add the new expressions to any existing SET expressions.
3520                Otherwise, this resets the expressions.
3521            dialect: the dialect used to parse the input expressions.
3522            copy: if `False`, modify this expression instance in-place.
3523            opts: other options to use to parse the input expressions.
3524        """
3525        return _apply_list_builder(
3526            *expressions,
3527            instance=self,
3528            arg="expressions",
3529            append=append,
3530            into=Expression,
3531            prefix=None,
3532            dialect=dialect,
3533            copy=copy,
3534            **opts,
3535        )
3536
3537    def where(
3538        self,
3539        *expressions: t.Optional[ExpOrStr],
3540        append: bool = True,
3541        dialect: DialectType = None,
3542        copy: bool = True,
3543        **opts,
3544    ) -> Select:
3545        """
3546        Append to or set the WHERE expressions.
3547
3548        Example:
3549            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3550            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3551
3552        Args:
3553            *expressions: the SQL code strings to parse.
3554                If an `Expression` instance is passed, it will be used as-is.
3555                Multiple expressions are combined with an AND operator.
3556            append: if `True`, AND the new expressions to any existing expression.
3557                Otherwise, this resets the expression.
3558            dialect: the dialect used to parse the input expressions.
3559            copy: if `False`, modify this expression instance in-place.
3560            opts: other options to use to parse the input expressions.
3561
3562        Returns:
3563            Select: the modified expression.
3564        """
3565        return _apply_conjunction_builder(
3566            *expressions,
3567            instance=self,
3568            arg="where",
3569            append=append,
3570            into=Where,
3571            dialect=dialect,
3572            copy=copy,
3573            **opts,
3574        )
3575
3576    def from_(
3577        self,
3578        expression: t.Optional[ExpOrStr] = None,
3579        dialect: DialectType = None,
3580        copy: bool = True,
3581        **opts,
3582    ) -> Update:
3583        """
3584        Set the FROM expression.
3585
3586        Example:
3587            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3588            'UPDATE my_table SET x = 1 FROM baz'
3589
3590        Args:
3591            expression : the SQL code strings to parse.
3592                If a `From` instance is passed, this is used as-is.
3593                If another `Expression` instance is passed, it will be wrapped in a `From`.
3594                If nothing is passed in then a from is not applied to the expression
3595            dialect: the dialect used to parse the input expression.
3596            copy: if `False`, modify this expression instance in-place.
3597            opts: other options to use to parse the input expressions.
3598
3599        Returns:
3600            The modified Update expression.
3601        """
3602        if not expression:
3603            return maybe_copy(self, copy)
3604
3605        return _apply_builder(
3606            expression=expression,
3607            instance=self,
3608            arg="from",
3609            into=From,
3610            prefix="FROM",
3611            dialect=dialect,
3612            copy=copy,
3613            **opts,
3614        )
3615
3616    def with_(
3617        self,
3618        alias: ExpOrStr,
3619        as_: ExpOrStr,
3620        recursive: t.Optional[bool] = None,
3621        materialized: t.Optional[bool] = None,
3622        append: bool = True,
3623        dialect: DialectType = None,
3624        copy: bool = True,
3625        **opts,
3626    ) -> Update:
3627        """
3628        Append to or set the common table expressions.
3629
3630        Example:
3631            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3632            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3633
3634        Args:
3635            alias: the SQL code string to parse as the table name.
3636                If an `Expression` instance is passed, this is used as-is.
3637            as_: the SQL code string to parse as the table expression.
3638                If an `Expression` instance is passed, it will be used as-is.
3639            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3640            materialized: set the MATERIALIZED part of the expression.
3641            append: if `True`, add to any existing expressions.
3642                Otherwise, this resets the expressions.
3643            dialect: the dialect used to parse the input expression.
3644            copy: if `False`, modify this expression instance in-place.
3645            opts: other options to use to parse the input expressions.
3646
3647        Returns:
3648            The modified expression.
3649        """
3650        return _apply_cte_builder(
3651            self,
3652            alias,
3653            as_,
3654            recursive=recursive,
3655            materialized=materialized,
3656            append=append,
3657            dialect=dialect,
3658            copy=copy,
3659            **opts,
3660        )
3661
3662
3663class Values(UDTF):
3664    arg_types = {"expressions": True, "alias": False}
3665
3666
3667class Var(Expression):
3668    pass
3669
3670
3671class Version(Expression):
3672    """
3673    Time travel, iceberg, bigquery etc
3674    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3675    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3676    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3677    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3678    this is either TIMESTAMP or VERSION
3679    kind is ("AS OF", "BETWEEN")
3680    """
3681
3682    arg_types = {"this": True, "kind": True, "expression": False}
3683
3684
3685class Schema(Expression):
3686    arg_types = {"this": False, "expressions": False}
3687
3688
3689# https://dev.mysql.com/doc/refman/8.0/en/select.html
3690# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
3691class Lock(Expression):
3692    arg_types = {"update": True, "expressions": False, "wait": False}
3693
3694
3695class Select(Query):
3696    arg_types = {
3697        "with": False,
3698        "kind": False,
3699        "expressions": False,
3700        "hint": False,
3701        "distinct": False,
3702        "into": False,
3703        "from": False,
3704        "operation_modifiers": False,
3705        **QUERY_MODIFIERS,
3706    }
3707
3708    def from_(
3709        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3710    ) -> Select:
3711        """
3712        Set the FROM expression.
3713
3714        Example:
3715            >>> Select().from_("tbl").select("x").sql()
3716            'SELECT x FROM tbl'
3717
3718        Args:
3719            expression : the SQL code strings to parse.
3720                If a `From` instance is passed, this is used as-is.
3721                If another `Expression` instance is passed, it will be wrapped in a `From`.
3722            dialect: the dialect used to parse the input expression.
3723            copy: if `False`, modify this expression instance in-place.
3724            opts: other options to use to parse the input expressions.
3725
3726        Returns:
3727            The modified Select expression.
3728        """
3729        return _apply_builder(
3730            expression=expression,
3731            instance=self,
3732            arg="from",
3733            into=From,
3734            prefix="FROM",
3735            dialect=dialect,
3736            copy=copy,
3737            **opts,
3738        )
3739
3740    def group_by(
3741        self,
3742        *expressions: t.Optional[ExpOrStr],
3743        append: bool = True,
3744        dialect: DialectType = None,
3745        copy: bool = True,
3746        **opts,
3747    ) -> Select:
3748        """
3749        Set the GROUP BY expression.
3750
3751        Example:
3752            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3753            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3754
3755        Args:
3756            *expressions: the SQL code strings to parse.
3757                If a `Group` instance is passed, this is used as-is.
3758                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3759                If nothing is passed in then a group by is not applied to the expression
3760            append: if `True`, add to any existing expressions.
3761                Otherwise, this flattens all the `Group` expression into a single expression.
3762            dialect: the dialect used to parse the input expression.
3763            copy: if `False`, modify this expression instance in-place.
3764            opts: other options to use to parse the input expressions.
3765
3766        Returns:
3767            The modified Select expression.
3768        """
3769        if not expressions:
3770            return self if not copy else self.copy()
3771
3772        return _apply_child_list_builder(
3773            *expressions,
3774            instance=self,
3775            arg="group",
3776            append=append,
3777            copy=copy,
3778            prefix="GROUP BY",
3779            into=Group,
3780            dialect=dialect,
3781            **opts,
3782        )
3783
3784    def sort_by(
3785        self,
3786        *expressions: t.Optional[ExpOrStr],
3787        append: bool = True,
3788        dialect: DialectType = None,
3789        copy: bool = True,
3790        **opts,
3791    ) -> Select:
3792        """
3793        Set the SORT BY expression.
3794
3795        Example:
3796            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3797            'SELECT x FROM tbl SORT BY x DESC'
3798
3799        Args:
3800            *expressions: the SQL code strings to parse.
3801                If a `Group` instance is passed, this is used as-is.
3802                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3803            append: if `True`, add to any existing expressions.
3804                Otherwise, this flattens all the `Order` expression into a single expression.
3805            dialect: the dialect used to parse the input expression.
3806            copy: if `False`, modify this expression instance in-place.
3807            opts: other options to use to parse the input expressions.
3808
3809        Returns:
3810            The modified Select expression.
3811        """
3812        return _apply_child_list_builder(
3813            *expressions,
3814            instance=self,
3815            arg="sort",
3816            append=append,
3817            copy=copy,
3818            prefix="SORT BY",
3819            into=Sort,
3820            dialect=dialect,
3821            **opts,
3822        )
3823
3824    def cluster_by(
3825        self,
3826        *expressions: t.Optional[ExpOrStr],
3827        append: bool = True,
3828        dialect: DialectType = None,
3829        copy: bool = True,
3830        **opts,
3831    ) -> Select:
3832        """
3833        Set the CLUSTER BY expression.
3834
3835        Example:
3836            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3837            'SELECT x FROM tbl CLUSTER BY x DESC'
3838
3839        Args:
3840            *expressions: the SQL code strings to parse.
3841                If a `Group` instance is passed, this is used as-is.
3842                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3843            append: if `True`, add to any existing expressions.
3844                Otherwise, this flattens all the `Order` expression into a single expression.
3845            dialect: the dialect used to parse the input expression.
3846            copy: if `False`, modify this expression instance in-place.
3847            opts: other options to use to parse the input expressions.
3848
3849        Returns:
3850            The modified Select expression.
3851        """
3852        return _apply_child_list_builder(
3853            *expressions,
3854            instance=self,
3855            arg="cluster",
3856            append=append,
3857            copy=copy,
3858            prefix="CLUSTER BY",
3859            into=Cluster,
3860            dialect=dialect,
3861            **opts,
3862        )
3863
3864    def select(
3865        self,
3866        *expressions: t.Optional[ExpOrStr],
3867        append: bool = True,
3868        dialect: DialectType = None,
3869        copy: bool = True,
3870        **opts,
3871    ) -> Select:
3872        return _apply_list_builder(
3873            *expressions,
3874            instance=self,
3875            arg="expressions",
3876            append=append,
3877            dialect=dialect,
3878            into=Expression,
3879            copy=copy,
3880            **opts,
3881        )
3882
3883    def lateral(
3884        self,
3885        *expressions: t.Optional[ExpOrStr],
3886        append: bool = True,
3887        dialect: DialectType = None,
3888        copy: bool = True,
3889        **opts,
3890    ) -> Select:
3891        """
3892        Append to or set the LATERAL expressions.
3893
3894        Example:
3895            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3896            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3897
3898        Args:
3899            *expressions: the SQL code strings to parse.
3900                If an `Expression` instance is passed, it will be used as-is.
3901            append: if `True`, add to any existing expressions.
3902                Otherwise, this resets the expressions.
3903            dialect: the dialect used to parse the input expressions.
3904            copy: if `False`, modify this expression instance in-place.
3905            opts: other options to use to parse the input expressions.
3906
3907        Returns:
3908            The modified Select expression.
3909        """
3910        return _apply_list_builder(
3911            *expressions,
3912            instance=self,
3913            arg="laterals",
3914            append=append,
3915            into=Lateral,
3916            prefix="LATERAL VIEW",
3917            dialect=dialect,
3918            copy=copy,
3919            **opts,
3920        )
3921
3922    def join(
3923        self,
3924        expression: ExpOrStr,
3925        on: t.Optional[ExpOrStr] = None,
3926        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3927        append: bool = True,
3928        join_type: t.Optional[str] = None,
3929        join_alias: t.Optional[Identifier | str] = None,
3930        dialect: DialectType = None,
3931        copy: bool = True,
3932        **opts,
3933    ) -> Select:
3934        """
3935        Append to or set the JOIN expressions.
3936
3937        Example:
3938            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3939            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3940
3941            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3942            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3943
3944            Use `join_type` to change the type of join:
3945
3946            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3947            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3948
3949        Args:
3950            expression: the SQL code string to parse.
3951                If an `Expression` instance is passed, it will be used as-is.
3952            on: optionally specify the join "on" criteria as a SQL string.
3953                If an `Expression` instance is passed, it will be used as-is.
3954            using: optionally specify the join "using" criteria as a SQL string.
3955                If an `Expression` instance is passed, it will be used as-is.
3956            append: if `True`, add to any existing expressions.
3957                Otherwise, this resets the expressions.
3958            join_type: if set, alter the parsed join type.
3959            join_alias: an optional alias for the joined source.
3960            dialect: the dialect used to parse the input expressions.
3961            copy: if `False`, modify this expression instance in-place.
3962            opts: other options to use to parse the input expressions.
3963
3964        Returns:
3965            Select: the modified expression.
3966        """
3967        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3968
3969        try:
3970            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3971        except ParseError:
3972            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3973
3974        join = expression if isinstance(expression, Join) else Join(this=expression)
3975
3976        if isinstance(join.this, Select):
3977            join.this.replace(join.this.subquery())
3978
3979        if join_type:
3980            method: t.Optional[Token]
3981            side: t.Optional[Token]
3982            kind: t.Optional[Token]
3983
3984            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3985
3986            if method:
3987                join.set("method", method.text)
3988            if side:
3989                join.set("side", side.text)
3990            if kind:
3991                join.set("kind", kind.text)
3992
3993        if on:
3994            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3995            join.set("on", on)
3996
3997        if using:
3998            join = _apply_list_builder(
3999                *ensure_list(using),
4000                instance=join,
4001                arg="using",
4002                append=append,
4003                copy=copy,
4004                into=Identifier,
4005                **opts,
4006            )
4007
4008        if join_alias:
4009            join.set("this", alias_(join.this, join_alias, table=True))
4010
4011        return _apply_list_builder(
4012            join,
4013            instance=self,
4014            arg="joins",
4015            append=append,
4016            copy=copy,
4017            **opts,
4018        )
4019
4020    def where(
4021        self,
4022        *expressions: t.Optional[ExpOrStr],
4023        append: bool = True,
4024        dialect: DialectType = None,
4025        copy: bool = True,
4026        **opts,
4027    ) -> Select:
4028        """
4029        Append to or set the WHERE expressions.
4030
4031        Example:
4032            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
4033            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
4034
4035        Args:
4036            *expressions: the SQL code strings to parse.
4037                If an `Expression` instance is passed, it will be used as-is.
4038                Multiple expressions are combined with an AND operator.
4039            append: if `True`, AND the new expressions to any existing expression.
4040                Otherwise, this resets the expression.
4041            dialect: the dialect used to parse the input expressions.
4042            copy: if `False`, modify this expression instance in-place.
4043            opts: other options to use to parse the input expressions.
4044
4045        Returns:
4046            Select: the modified expression.
4047        """
4048        return _apply_conjunction_builder(
4049            *expressions,
4050            instance=self,
4051            arg="where",
4052            append=append,
4053            into=Where,
4054            dialect=dialect,
4055            copy=copy,
4056            **opts,
4057        )
4058
4059    def having(
4060        self,
4061        *expressions: t.Optional[ExpOrStr],
4062        append: bool = True,
4063        dialect: DialectType = None,
4064        copy: bool = True,
4065        **opts,
4066    ) -> Select:
4067        """
4068        Append to or set the HAVING expressions.
4069
4070        Example:
4071            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4072            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4073
4074        Args:
4075            *expressions: the SQL code strings to parse.
4076                If an `Expression` instance is passed, it will be used as-is.
4077                Multiple expressions are combined with an AND operator.
4078            append: if `True`, AND the new expressions to any existing expression.
4079                Otherwise, this resets the expression.
4080            dialect: the dialect used to parse the input expressions.
4081            copy: if `False`, modify this expression instance in-place.
4082            opts: other options to use to parse the input expressions.
4083
4084        Returns:
4085            The modified Select expression.
4086        """
4087        return _apply_conjunction_builder(
4088            *expressions,
4089            instance=self,
4090            arg="having",
4091            append=append,
4092            into=Having,
4093            dialect=dialect,
4094            copy=copy,
4095            **opts,
4096        )
4097
4098    def window(
4099        self,
4100        *expressions: t.Optional[ExpOrStr],
4101        append: bool = True,
4102        dialect: DialectType = None,
4103        copy: bool = True,
4104        **opts,
4105    ) -> Select:
4106        return _apply_list_builder(
4107            *expressions,
4108            instance=self,
4109            arg="windows",
4110            append=append,
4111            into=Window,
4112            dialect=dialect,
4113            copy=copy,
4114            **opts,
4115        )
4116
4117    def qualify(
4118        self,
4119        *expressions: t.Optional[ExpOrStr],
4120        append: bool = True,
4121        dialect: DialectType = None,
4122        copy: bool = True,
4123        **opts,
4124    ) -> Select:
4125        return _apply_conjunction_builder(
4126            *expressions,
4127            instance=self,
4128            arg="qualify",
4129            append=append,
4130            into=Qualify,
4131            dialect=dialect,
4132            copy=copy,
4133            **opts,
4134        )
4135
4136    def distinct(
4137        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4138    ) -> Select:
4139        """
4140        Set the OFFSET expression.
4141
4142        Example:
4143            >>> Select().from_("tbl").select("x").distinct().sql()
4144            'SELECT DISTINCT x FROM tbl'
4145
4146        Args:
4147            ons: the expressions to distinct on
4148            distinct: whether the Select should be distinct
4149            copy: if `False`, modify this expression instance in-place.
4150
4151        Returns:
4152            Select: the modified expression.
4153        """
4154        instance = maybe_copy(self, copy)
4155        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4156        instance.set("distinct", Distinct(on=on) if distinct else None)
4157        return instance
4158
4159    def ctas(
4160        self,
4161        table: ExpOrStr,
4162        properties: t.Optional[t.Dict] = None,
4163        dialect: DialectType = None,
4164        copy: bool = True,
4165        **opts,
4166    ) -> Create:
4167        """
4168        Convert this expression to a CREATE TABLE AS statement.
4169
4170        Example:
4171            >>> Select().select("*").from_("tbl").ctas("x").sql()
4172            'CREATE TABLE x AS SELECT * FROM tbl'
4173
4174        Args:
4175            table: the SQL code string to parse as the table name.
4176                If another `Expression` instance is passed, it will be used as-is.
4177            properties: an optional mapping of table properties
4178            dialect: the dialect used to parse the input table.
4179            copy: if `False`, modify this expression instance in-place.
4180            opts: other options to use to parse the input table.
4181
4182        Returns:
4183            The new Create expression.
4184        """
4185        instance = maybe_copy(self, copy)
4186        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4187
4188        properties_expression = None
4189        if properties:
4190            properties_expression = Properties.from_dict(properties)
4191
4192        return Create(
4193            this=table_expression,
4194            kind="TABLE",
4195            expression=instance,
4196            properties=properties_expression,
4197        )
4198
4199    def lock(self, update: bool = True, copy: bool = True) -> Select:
4200        """
4201        Set the locking read mode for this expression.
4202
4203        Examples:
4204            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4205            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4206
4207            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4208            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4209
4210        Args:
4211            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4212            copy: if `False`, modify this expression instance in-place.
4213
4214        Returns:
4215            The modified expression.
4216        """
4217        inst = maybe_copy(self, copy)
4218        inst.set("locks", [Lock(update=update)])
4219
4220        return inst
4221
4222    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4223        """
4224        Set hints for this expression.
4225
4226        Examples:
4227            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4228            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4229
4230        Args:
4231            hints: The SQL code strings to parse as the hints.
4232                If an `Expression` instance is passed, it will be used as-is.
4233            dialect: The dialect used to parse the hints.
4234            copy: If `False`, modify this expression instance in-place.
4235
4236        Returns:
4237            The modified expression.
4238        """
4239        inst = maybe_copy(self, copy)
4240        inst.set(
4241            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4242        )
4243
4244        return inst
4245
4246    @property
4247    def named_selects(self) -> t.List[str]:
4248        return [e.output_name for e in self.expressions if e.alias_or_name]
4249
4250    @property
4251    def is_star(self) -> bool:
4252        return any(expression.is_star for expression in self.expressions)
4253
4254    @property
4255    def selects(self) -> t.List[Expression]:
4256        return self.expressions
4257
4258
4259UNWRAPPED_QUERIES = (Select, SetOperation)
4260
4261
4262class Subquery(DerivedTable, Query):
4263    arg_types = {
4264        "this": True,
4265        "alias": False,
4266        "with": False,
4267        **QUERY_MODIFIERS,
4268    }
4269
4270    def unnest(self):
4271        """Returns the first non subquery."""
4272        expression = self
4273        while isinstance(expression, Subquery):
4274            expression = expression.this
4275        return expression
4276
4277    def unwrap(self) -> Subquery:
4278        expression = self
4279        while expression.same_parent and expression.is_wrapper:
4280            expression = t.cast(Subquery, expression.parent)
4281        return expression
4282
4283    def select(
4284        self,
4285        *expressions: t.Optional[ExpOrStr],
4286        append: bool = True,
4287        dialect: DialectType = None,
4288        copy: bool = True,
4289        **opts,
4290    ) -> Subquery:
4291        this = maybe_copy(self, copy)
4292        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4293        return this
4294
4295    @property
4296    def is_wrapper(self) -> bool:
4297        """
4298        Whether this Subquery acts as a simple wrapper around another expression.
4299
4300        SELECT * FROM (((SELECT * FROM t)))
4301                      ^
4302                      This corresponds to a "wrapper" Subquery node
4303        """
4304        return all(v is None for k, v in self.args.items() if k != "this")
4305
4306    @property
4307    def is_star(self) -> bool:
4308        return self.this.is_star
4309
4310    @property
4311    def output_name(self) -> str:
4312        return self.alias
4313
4314
4315class TableSample(Expression):
4316    arg_types = {
4317        "expressions": False,
4318        "method": False,
4319        "bucket_numerator": False,
4320        "bucket_denominator": False,
4321        "bucket_field": False,
4322        "percent": False,
4323        "rows": False,
4324        "size": False,
4325        "seed": False,
4326    }
4327
4328
4329class Tag(Expression):
4330    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4331
4332    arg_types = {
4333        "this": False,
4334        "prefix": False,
4335        "postfix": False,
4336    }
4337
4338
4339# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
4340# https://duckdb.org/docs/sql/statements/pivot
4341class Pivot(Expression):
4342    arg_types = {
4343        "this": False,
4344        "alias": False,
4345        "expressions": False,
4346        "fields": False,
4347        "unpivot": False,
4348        "using": False,
4349        "group": False,
4350        "columns": False,
4351        "include_nulls": False,
4352        "default_on_null": False,
4353        "into": False,
4354    }
4355
4356    @property
4357    def unpivot(self) -> bool:
4358        return bool(self.args.get("unpivot"))
4359
4360    @property
4361    def fields(self) -> t.List[Expression]:
4362        return self.args.get("fields", [])
4363
4364
4365# https://duckdb.org/docs/sql/statements/unpivot#simplified-unpivot-syntax
4366# UNPIVOT ... INTO [NAME <col_name> VALUE <col_value>][...,]
4367class UnpivotColumns(Expression):
4368    arg_types = {"this": True, "expressions": True}
4369
4370
4371class Window(Condition):
4372    arg_types = {
4373        "this": True,
4374        "partition_by": False,
4375        "order": False,
4376        "spec": False,
4377        "alias": False,
4378        "over": False,
4379        "first": False,
4380    }
4381
4382
4383class WindowSpec(Expression):
4384    arg_types = {
4385        "kind": False,
4386        "start": False,
4387        "start_side": False,
4388        "end": False,
4389        "end_side": False,
4390    }
4391
4392
4393class PreWhere(Expression):
4394    pass
4395
4396
4397class Where(Expression):
4398    pass
4399
4400
4401class Star(Expression):
4402    arg_types = {"except": False, "replace": False, "rename": False}
4403
4404    @property
4405    def name(self) -> str:
4406        return "*"
4407
4408    @property
4409    def output_name(self) -> str:
4410        return self.name
4411
4412
4413class Parameter(Condition):
4414    arg_types = {"this": True, "expression": False}
4415
4416
4417class SessionParameter(Condition):
4418    arg_types = {"this": True, "kind": False}
4419
4420
4421class Placeholder(Condition):
4422    arg_types = {"this": False, "kind": False}
4423
4424    @property
4425    def name(self) -> str:
4426        return self.this or "?"
4427
4428
4429class Null(Condition):
4430    arg_types: t.Dict[str, t.Any] = {}
4431
4432    @property
4433    def name(self) -> str:
4434        return "NULL"
4435
4436    def to_py(self) -> Lit[None]:
4437        return None
4438
4439
4440class Boolean(Condition):
4441    def to_py(self) -> bool:
4442        return self.this
4443
4444
4445class DataTypeParam(Expression):
4446    arg_types = {"this": True, "expression": False}
4447
4448    @property
4449    def name(self) -> str:
4450        return self.this.name
4451
4452
4453# The `nullable` arg is helpful when transpiling types from other dialects to ClickHouse, which
4454# assumes non-nullable types by default. Values `None` and `True` mean the type is nullable.
4455class DataType(Expression):
4456    arg_types = {
4457        "this": True,
4458        "expressions": False,
4459        "nested": False,
4460        "values": False,
4461        "prefix": False,
4462        "kind": False,
4463        "nullable": False,
4464    }
4465
4466    class Type(AutoName):
4467        ARRAY = auto()
4468        AGGREGATEFUNCTION = auto()
4469        SIMPLEAGGREGATEFUNCTION = auto()
4470        BIGDECIMAL = auto()
4471        BIGINT = auto()
4472        BIGSERIAL = auto()
4473        BINARY = auto()
4474        BIT = auto()
4475        BLOB = auto()
4476        BOOLEAN = auto()
4477        BPCHAR = auto()
4478        CHAR = auto()
4479        DATE = auto()
4480        DATE32 = auto()
4481        DATEMULTIRANGE = auto()
4482        DATERANGE = auto()
4483        DATETIME = auto()
4484        DATETIME2 = auto()
4485        DATETIME64 = auto()
4486        DECIMAL = auto()
4487        DECIMAL32 = auto()
4488        DECIMAL64 = auto()
4489        DECIMAL128 = auto()
4490        DECIMAL256 = auto()
4491        DOUBLE = auto()
4492        DYNAMIC = auto()
4493        ENUM = auto()
4494        ENUM8 = auto()
4495        ENUM16 = auto()
4496        FIXEDSTRING = auto()
4497        FLOAT = auto()
4498        GEOGRAPHY = auto()
4499        GEOMETRY = auto()
4500        POINT = auto()
4501        RING = auto()
4502        LINESTRING = auto()
4503        MULTILINESTRING = auto()
4504        POLYGON = auto()
4505        MULTIPOLYGON = auto()
4506        HLLSKETCH = auto()
4507        HSTORE = auto()
4508        IMAGE = auto()
4509        INET = auto()
4510        INT = auto()
4511        INT128 = auto()
4512        INT256 = auto()
4513        INT4MULTIRANGE = auto()
4514        INT4RANGE = auto()
4515        INT8MULTIRANGE = auto()
4516        INT8RANGE = auto()
4517        INTERVAL = auto()
4518        IPADDRESS = auto()
4519        IPPREFIX = auto()
4520        IPV4 = auto()
4521        IPV6 = auto()
4522        JSON = auto()
4523        JSONB = auto()
4524        LIST = auto()
4525        LONGBLOB = auto()
4526        LONGTEXT = auto()
4527        LOWCARDINALITY = auto()
4528        MAP = auto()
4529        MEDIUMBLOB = auto()
4530        MEDIUMINT = auto()
4531        MEDIUMTEXT = auto()
4532        MONEY = auto()
4533        NAME = auto()
4534        NCHAR = auto()
4535        NESTED = auto()
4536        NOTHING = auto()
4537        NULL = auto()
4538        NUMMULTIRANGE = auto()
4539        NUMRANGE = auto()
4540        NVARCHAR = auto()
4541        OBJECT = auto()
4542        RANGE = auto()
4543        ROWVERSION = auto()
4544        SERIAL = auto()
4545        SET = auto()
4546        SMALLDATETIME = auto()
4547        SMALLINT = auto()
4548        SMALLMONEY = auto()
4549        SMALLSERIAL = auto()
4550        STRUCT = auto()
4551        SUPER = auto()
4552        TEXT = auto()
4553        TINYBLOB = auto()
4554        TINYTEXT = auto()
4555        TIME = auto()
4556        TIMETZ = auto()
4557        TIMESTAMP = auto()
4558        TIMESTAMPNTZ = auto()
4559        TIMESTAMPLTZ = auto()
4560        TIMESTAMPTZ = auto()
4561        TIMESTAMP_S = auto()
4562        TIMESTAMP_MS = auto()
4563        TIMESTAMP_NS = auto()
4564        TINYINT = auto()
4565        TSMULTIRANGE = auto()
4566        TSRANGE = auto()
4567        TSTZMULTIRANGE = auto()
4568        TSTZRANGE = auto()
4569        UBIGINT = auto()
4570        UINT = auto()
4571        UINT128 = auto()
4572        UINT256 = auto()
4573        UMEDIUMINT = auto()
4574        UDECIMAL = auto()
4575        UDOUBLE = auto()
4576        UNION = auto()
4577        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4578        USERDEFINED = "USER-DEFINED"
4579        USMALLINT = auto()
4580        UTINYINT = auto()
4581        UUID = auto()
4582        VARBINARY = auto()
4583        VARCHAR = auto()
4584        VARIANT = auto()
4585        VECTOR = auto()
4586        XML = auto()
4587        YEAR = auto()
4588        TDIGEST = auto()
4589
4590    STRUCT_TYPES = {
4591        Type.NESTED,
4592        Type.OBJECT,
4593        Type.STRUCT,
4594        Type.UNION,
4595    }
4596
4597    ARRAY_TYPES = {
4598        Type.ARRAY,
4599        Type.LIST,
4600    }
4601
4602    NESTED_TYPES = {
4603        *STRUCT_TYPES,
4604        *ARRAY_TYPES,
4605        Type.MAP,
4606    }
4607
4608    TEXT_TYPES = {
4609        Type.CHAR,
4610        Type.NCHAR,
4611        Type.NVARCHAR,
4612        Type.TEXT,
4613        Type.VARCHAR,
4614        Type.NAME,
4615    }
4616
4617    SIGNED_INTEGER_TYPES = {
4618        Type.BIGINT,
4619        Type.INT,
4620        Type.INT128,
4621        Type.INT256,
4622        Type.MEDIUMINT,
4623        Type.SMALLINT,
4624        Type.TINYINT,
4625    }
4626
4627    UNSIGNED_INTEGER_TYPES = {
4628        Type.UBIGINT,
4629        Type.UINT,
4630        Type.UINT128,
4631        Type.UINT256,
4632        Type.UMEDIUMINT,
4633        Type.USMALLINT,
4634        Type.UTINYINT,
4635    }
4636
4637    INTEGER_TYPES = {
4638        *SIGNED_INTEGER_TYPES,
4639        *UNSIGNED_INTEGER_TYPES,
4640        Type.BIT,
4641    }
4642
4643    FLOAT_TYPES = {
4644        Type.DOUBLE,
4645        Type.FLOAT,
4646    }
4647
4648    REAL_TYPES = {
4649        *FLOAT_TYPES,
4650        Type.BIGDECIMAL,
4651        Type.DECIMAL,
4652        Type.DECIMAL32,
4653        Type.DECIMAL64,
4654        Type.DECIMAL128,
4655        Type.DECIMAL256,
4656        Type.MONEY,
4657        Type.SMALLMONEY,
4658        Type.UDECIMAL,
4659        Type.UDOUBLE,
4660    }
4661
4662    NUMERIC_TYPES = {
4663        *INTEGER_TYPES,
4664        *REAL_TYPES,
4665    }
4666
4667    TEMPORAL_TYPES = {
4668        Type.DATE,
4669        Type.DATE32,
4670        Type.DATETIME,
4671        Type.DATETIME2,
4672        Type.DATETIME64,
4673        Type.SMALLDATETIME,
4674        Type.TIME,
4675        Type.TIMESTAMP,
4676        Type.TIMESTAMPNTZ,
4677        Type.TIMESTAMPLTZ,
4678        Type.TIMESTAMPTZ,
4679        Type.TIMESTAMP_MS,
4680        Type.TIMESTAMP_NS,
4681        Type.TIMESTAMP_S,
4682        Type.TIMETZ,
4683    }
4684
4685    @classmethod
4686    def build(
4687        cls,
4688        dtype: DATA_TYPE,
4689        dialect: DialectType = None,
4690        udt: bool = False,
4691        copy: bool = True,
4692        **kwargs,
4693    ) -> DataType:
4694        """
4695        Constructs a DataType object.
4696
4697        Args:
4698            dtype: the data type of interest.
4699            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4700            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4701                DataType, thus creating a user-defined type.
4702            copy: whether to copy the data type.
4703            kwargs: additional arguments to pass in the constructor of DataType.
4704
4705        Returns:
4706            The constructed DataType object.
4707        """
4708        from sqlglot import parse_one
4709
4710        if isinstance(dtype, str):
4711            if dtype.upper() == "UNKNOWN":
4712                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4713
4714            try:
4715                data_type_exp = parse_one(
4716                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4717                )
4718            except ParseError:
4719                if udt:
4720                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4721                raise
4722        elif isinstance(dtype, DataType.Type):
4723            data_type_exp = DataType(this=dtype)
4724        elif isinstance(dtype, DataType):
4725            return maybe_copy(dtype, copy)
4726        else:
4727            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4728
4729        return DataType(**{**data_type_exp.args, **kwargs})
4730
4731    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4732        """
4733        Checks whether this DataType matches one of the provided data types. Nested types or precision
4734        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4735
4736        Args:
4737            dtypes: the data types to compare this DataType to.
4738            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4739                If false, it means that NULLABLE<INT> is equivalent to INT.
4740
4741        Returns:
4742            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4743        """
4744        self_is_nullable = self.args.get("nullable")
4745        for dtype in dtypes:
4746            other_type = DataType.build(dtype, copy=False, udt=True)
4747            other_is_nullable = other_type.args.get("nullable")
4748            if (
4749                other_type.expressions
4750                or (check_nullable and (self_is_nullable or other_is_nullable))
4751                or self.this == DataType.Type.USERDEFINED
4752                or other_type.this == DataType.Type.USERDEFINED
4753            ):
4754                matches = self == other_type
4755            else:
4756                matches = self.this == other_type.this
4757
4758            if matches:
4759                return True
4760        return False
4761
4762
4763DATA_TYPE = t.Union[str, DataType, DataType.Type]
4764
4765
4766# https://www.postgresql.org/docs/15/datatype-pseudo.html
4767class PseudoType(DataType):
4768    arg_types = {"this": True}
4769
4770
4771# https://www.postgresql.org/docs/15/datatype-oid.html
4772class ObjectIdentifier(DataType):
4773    arg_types = {"this": True}
4774
4775
4776# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4777class SubqueryPredicate(Predicate):
4778    pass
4779
4780
4781class All(SubqueryPredicate):
4782    pass
4783
4784
4785class Any(SubqueryPredicate):
4786    pass
4787
4788
4789# Commands to interact with the databases or engines. For most of the command
4790# expressions we parse whatever comes after the command's name as a string.
4791class Command(Expression):
4792    arg_types = {"this": True, "expression": False}
4793
4794
4795class Transaction(Expression):
4796    arg_types = {"this": False, "modes": False, "mark": False}
4797
4798
4799class Commit(Expression):
4800    arg_types = {"chain": False, "this": False, "durability": False}
4801
4802
4803class Rollback(Expression):
4804    arg_types = {"savepoint": False, "this": False}
4805
4806
4807class Alter(Expression):
4808    arg_types = {
4809        "this": True,
4810        "kind": True,
4811        "actions": True,
4812        "exists": False,
4813        "only": False,
4814        "options": False,
4815        "cluster": False,
4816        "not_valid": False,
4817    }
4818
4819    @property
4820    def kind(self) -> t.Optional[str]:
4821        kind = self.args.get("kind")
4822        return kind and kind.upper()
4823
4824    @property
4825    def actions(self) -> t.List[Expression]:
4826        return self.args.get("actions") or []
4827
4828
4829class Analyze(Expression):
4830    arg_types = {
4831        "kind": False,
4832        "this": False,
4833        "options": False,
4834        "mode": False,
4835        "partition": False,
4836        "expression": False,
4837        "properties": False,
4838    }
4839
4840
4841class AnalyzeStatistics(Expression):
4842    arg_types = {
4843        "kind": True,
4844        "option": False,
4845        "this": False,
4846        "expressions": False,
4847    }
4848
4849
4850class AnalyzeHistogram(Expression):
4851    arg_types = {
4852        "this": True,
4853        "expressions": True,
4854        "expression": False,
4855        "update_options": False,
4856    }
4857
4858
4859class AnalyzeSample(Expression):
4860    arg_types = {"kind": True, "sample": True}
4861
4862
4863class AnalyzeListChainedRows(Expression):
4864    arg_types = {"expression": False}
4865
4866
4867class AnalyzeDelete(Expression):
4868    arg_types = {"kind": False}
4869
4870
4871class AnalyzeWith(Expression):
4872    arg_types = {"expressions": True}
4873
4874
4875class AnalyzeValidate(Expression):
4876    arg_types = {
4877        "kind": True,
4878        "this": False,
4879        "expression": False,
4880    }
4881
4882
4883class AnalyzeColumns(Expression):
4884    pass
4885
4886
4887class UsingData(Expression):
4888    pass
4889
4890
4891class AddConstraint(Expression):
4892    arg_types = {"expressions": True}
4893
4894
4895class AttachOption(Expression):
4896    arg_types = {"this": True, "expression": False}
4897
4898
4899class DropPartition(Expression):
4900    arg_types = {"expressions": True, "exists": False}
4901
4902
4903# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#replace-partition
4904class ReplacePartition(Expression):
4905    arg_types = {"expression": True, "source": True}
4906
4907
4908# Binary expressions like (ADD a b)
4909class Binary(Condition):
4910    arg_types = {"this": True, "expression": True}
4911
4912    @property
4913    def left(self) -> Expression:
4914        return self.this
4915
4916    @property
4917    def right(self) -> Expression:
4918        return self.expression
4919
4920
4921class Add(Binary):
4922    pass
4923
4924
4925class Connector(Binary):
4926    pass
4927
4928
4929class BitwiseAnd(Binary):
4930    pass
4931
4932
4933class BitwiseLeftShift(Binary):
4934    pass
4935
4936
4937class BitwiseOr(Binary):
4938    pass
4939
4940
4941class BitwiseRightShift(Binary):
4942    pass
4943
4944
4945class BitwiseXor(Binary):
4946    pass
4947
4948
4949class Div(Binary):
4950    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4951
4952
4953class Overlaps(Binary):
4954    pass
4955
4956
4957class Dot(Binary):
4958    @property
4959    def is_star(self) -> bool:
4960        return self.expression.is_star
4961
4962    @property
4963    def name(self) -> str:
4964        return self.expression.name
4965
4966    @property
4967    def output_name(self) -> str:
4968        return self.name
4969
4970    @classmethod
4971    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4972        """Build a Dot object with a sequence of expressions."""
4973        if len(expressions) < 2:
4974            raise ValueError("Dot requires >= 2 expressions.")
4975
4976        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4977
4978    @property
4979    def parts(self) -> t.List[Expression]:
4980        """Return the parts of a table / column in order catalog, db, table."""
4981        this, *parts = self.flatten()
4982
4983        parts.reverse()
4984
4985        for arg in COLUMN_PARTS:
4986            part = this.args.get(arg)
4987
4988            if isinstance(part, Expression):
4989                parts.append(part)
4990
4991        parts.reverse()
4992        return parts
4993
4994
4995class DPipe(Binary):
4996    arg_types = {"this": True, "expression": True, "safe": False}
4997
4998
4999class EQ(Binary, Predicate):
5000    pass
5001
5002
5003class NullSafeEQ(Binary, Predicate):
5004    pass
5005
5006
5007class NullSafeNEQ(Binary, Predicate):
5008    pass
5009
5010
5011# Represents e.g. := in DuckDB which is mostly used for setting parameters
5012class PropertyEQ(Binary):
5013    pass
5014
5015
5016class Distance(Binary):
5017    pass
5018
5019
5020class Escape(Binary):
5021    pass
5022
5023
5024class Glob(Binary, Predicate):
5025    pass
5026
5027
5028class GT(Binary, Predicate):
5029    pass
5030
5031
5032class GTE(Binary, Predicate):
5033    pass
5034
5035
5036class ILike(Binary, Predicate):
5037    pass
5038
5039
5040class ILikeAny(Binary, Predicate):
5041    pass
5042
5043
5044class IntDiv(Binary):
5045    pass
5046
5047
5048class Is(Binary, Predicate):
5049    pass
5050
5051
5052class Kwarg(Binary):
5053    """Kwarg in special functions like func(kwarg => y)."""
5054
5055
5056class Like(Binary, Predicate):
5057    pass
5058
5059
5060class LikeAny(Binary, Predicate):
5061    pass
5062
5063
5064class LT(Binary, Predicate):
5065    pass
5066
5067
5068class LTE(Binary, Predicate):
5069    pass
5070
5071
5072class Mod(Binary):
5073    pass
5074
5075
5076class Mul(Binary):
5077    pass
5078
5079
5080class NEQ(Binary, Predicate):
5081    pass
5082
5083
5084# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
5085class Operator(Binary):
5086    arg_types = {"this": True, "operator": True, "expression": True}
5087
5088
5089class SimilarTo(Binary, Predicate):
5090    pass
5091
5092
5093class Slice(Binary):
5094    arg_types = {"this": False, "expression": False}
5095
5096
5097class Sub(Binary):
5098    pass
5099
5100
5101# Unary Expressions
5102# (NOT a)
5103class Unary(Condition):
5104    pass
5105
5106
5107class BitwiseNot(Unary):
5108    pass
5109
5110
5111class Not(Unary):
5112    pass
5113
5114
5115class Paren(Unary):
5116    @property
5117    def output_name(self) -> str:
5118        return self.this.name
5119
5120
5121class Neg(Unary):
5122    def to_py(self) -> int | Decimal:
5123        if self.is_number:
5124            return self.this.to_py() * -1
5125        return super().to_py()
5126
5127
5128class Alias(Expression):
5129    arg_types = {"this": True, "alias": False}
5130
5131    @property
5132    def output_name(self) -> str:
5133        return self.alias
5134
5135
5136# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
5137# other dialects require identifiers. This enables us to transpile between them easily.
5138class PivotAlias(Alias):
5139    pass
5140
5141
5142# Represents Snowflake's ANY [ ORDER BY ... ] syntax
5143# https://docs.snowflake.com/en/sql-reference/constructs/pivot
5144class PivotAny(Expression):
5145    arg_types = {"this": False}
5146
5147
5148class Aliases(Expression):
5149    arg_types = {"this": True, "expressions": True}
5150
5151    @property
5152    def aliases(self):
5153        return self.expressions
5154
5155
5156# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
5157class AtIndex(Expression):
5158    arg_types = {"this": True, "expression": True}
5159
5160
5161class AtTimeZone(Expression):
5162    arg_types = {"this": True, "zone": True}
5163
5164
5165class FromTimeZone(Expression):
5166    arg_types = {"this": True, "zone": True}
5167
5168
5169class Between(Predicate):
5170    arg_types = {"this": True, "low": True, "high": True}
5171
5172
5173class Bracket(Condition):
5174    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5175    arg_types = {
5176        "this": True,
5177        "expressions": True,
5178        "offset": False,
5179        "safe": False,
5180        "returns_list_for_maps": False,
5181    }
5182
5183    @property
5184    def output_name(self) -> str:
5185        if len(self.expressions) == 1:
5186            return self.expressions[0].output_name
5187
5188        return super().output_name
5189
5190
5191class Distinct(Expression):
5192    arg_types = {"expressions": False, "on": False}
5193
5194
5195class In(Predicate):
5196    arg_types = {
5197        "this": True,
5198        "expressions": False,
5199        "query": False,
5200        "unnest": False,
5201        "field": False,
5202        "is_global": False,
5203    }
5204
5205
5206# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
5207class ForIn(Expression):
5208    arg_types = {"this": True, "expression": True}
5209
5210
5211class TimeUnit(Expression):
5212    """Automatically converts unit arg into a var."""
5213
5214    arg_types = {"unit": False}
5215
5216    UNABBREVIATED_UNIT_NAME = {
5217        "D": "DAY",
5218        "H": "HOUR",
5219        "M": "MINUTE",
5220        "MS": "MILLISECOND",
5221        "NS": "NANOSECOND",
5222        "Q": "QUARTER",
5223        "S": "SECOND",
5224        "US": "MICROSECOND",
5225        "W": "WEEK",
5226        "Y": "YEAR",
5227    }
5228
5229    VAR_LIKE = (Column, Literal, Var)
5230
5231    def __init__(self, **args):
5232        unit = args.get("unit")
5233        if isinstance(unit, self.VAR_LIKE):
5234            args["unit"] = Var(
5235                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5236            )
5237        elif isinstance(unit, Week):
5238            unit.set("this", Var(this=unit.this.name.upper()))
5239
5240        super().__init__(**args)
5241
5242    @property
5243    def unit(self) -> t.Optional[Var | IntervalSpan]:
5244        return self.args.get("unit")
5245
5246
5247class IntervalOp(TimeUnit):
5248    arg_types = {"unit": False, "expression": True}
5249
5250    def interval(self):
5251        return Interval(
5252            this=self.expression.copy(),
5253            unit=self.unit.copy() if self.unit else None,
5254        )
5255
5256
5257# https://www.oracletutorial.com/oracle-basics/oracle-interval/
5258# https://trino.io/docs/current/language/types.html#interval-day-to-second
5259# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
5260class IntervalSpan(DataType):
5261    arg_types = {"this": True, "expression": True}
5262
5263
5264class Interval(TimeUnit):
5265    arg_types = {"this": False, "unit": False}
5266
5267
5268class IgnoreNulls(Expression):
5269    pass
5270
5271
5272class RespectNulls(Expression):
5273    pass
5274
5275
5276# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
5277class HavingMax(Expression):
5278    arg_types = {"this": True, "expression": True, "max": True}
5279
5280
5281# Functions
5282class Func(Condition):
5283    """
5284    The base class for all function expressions.
5285
5286    Attributes:
5287        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5288            treated as a variable length argument and the argument's value will be stored as a list.
5289        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5290            function expression. These values are used to map this node to a name during parsing as
5291            well as to provide the function's name during SQL string generation. By default the SQL
5292            name is set to the expression's class name transformed to snake case.
5293    """
5294
5295    is_var_len_args = False
5296
5297    @classmethod
5298    def from_arg_list(cls, args):
5299        if cls.is_var_len_args:
5300            all_arg_keys = list(cls.arg_types)
5301            # If this function supports variable length argument treat the last argument as such.
5302            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5303            num_non_var = len(non_var_len_arg_keys)
5304
5305            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5306            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5307        else:
5308            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5309
5310        return cls(**args_dict)
5311
5312    @classmethod
5313    def sql_names(cls):
5314        if cls is Func:
5315            raise NotImplementedError(
5316                "SQL name is only supported by concrete function implementations"
5317            )
5318        if "_sql_names" not in cls.__dict__:
5319            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5320        return cls._sql_names
5321
5322    @classmethod
5323    def sql_name(cls):
5324        return cls.sql_names()[0]
5325
5326    @classmethod
5327    def default_parser_mappings(cls):
5328        return {name: cls.from_arg_list for name in cls.sql_names()}
5329
5330
5331class AggFunc(Func):
5332    pass
5333
5334
5335class ParameterizedAgg(AggFunc):
5336    arg_types = {"this": True, "expressions": True, "params": True}
5337
5338
5339class Abs(Func):
5340    pass
5341
5342
5343class ArgMax(AggFunc):
5344    arg_types = {"this": True, "expression": True, "count": False}
5345    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
5346
5347
5348class ArgMin(AggFunc):
5349    arg_types = {"this": True, "expression": True, "count": False}
5350    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
5351
5352
5353class ApproxTopK(AggFunc):
5354    arg_types = {"this": True, "expression": False, "counters": False}
5355
5356
5357class Flatten(Func):
5358    pass
5359
5360
5361# https://spark.apache.org/docs/latest/api/sql/index.html#transform
5362class Transform(Func):
5363    arg_types = {"this": True, "expression": True}
5364
5365
5366class Anonymous(Func):
5367    arg_types = {"this": True, "expressions": False}
5368    is_var_len_args = True
5369
5370    @property
5371    def name(self) -> str:
5372        return self.this if isinstance(self.this, str) else self.this.name
5373
5374
5375class AnonymousAggFunc(AggFunc):
5376    arg_types = {"this": True, "expressions": False}
5377    is_var_len_args = True
5378
5379
5380# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
5381class CombinedAggFunc(AnonymousAggFunc):
5382    arg_types = {"this": True, "expressions": False}
5383
5384
5385class CombinedParameterizedAgg(ParameterizedAgg):
5386    arg_types = {"this": True, "expressions": True, "params": True}
5387
5388
5389# https://docs.snowflake.com/en/sql-reference/functions/hll
5390# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
5391class Hll(AggFunc):
5392    arg_types = {"this": True, "expressions": False}
5393    is_var_len_args = True
5394
5395
5396class ApproxDistinct(AggFunc):
5397    arg_types = {"this": True, "accuracy": False}
5398    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
5399
5400
5401class Apply(Func):
5402    arg_types = {"this": True, "expression": True}
5403
5404
5405class Array(Func):
5406    arg_types = {"expressions": False, "bracket_notation": False}
5407    is_var_len_args = True
5408
5409
5410# https://docs.snowflake.com/en/sql-reference/functions/to_array
5411class ToArray(Func):
5412    pass
5413
5414
5415# https://materialize.com/docs/sql/types/list/
5416class List(Func):
5417    arg_types = {"expressions": False}
5418    is_var_len_args = True
5419
5420
5421# String pad, kind True -> LPAD, False -> RPAD
5422class Pad(Func):
5423    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
5424
5425
5426# https://docs.snowflake.com/en/sql-reference/functions/to_char
5427# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
5428class ToChar(Func):
5429    arg_types = {"this": True, "format": False, "nlsparam": False}
5430
5431
5432# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
5433# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
5434class ToNumber(Func):
5435    arg_types = {
5436        "this": True,
5437        "format": False,
5438        "nlsparam": False,
5439        "precision": False,
5440        "scale": False,
5441    }
5442
5443
5444# https://docs.snowflake.com/en/sql-reference/functions/to_double
5445class ToDouble(Func):
5446    arg_types = {
5447        "this": True,
5448        "format": False,
5449    }
5450
5451
5452class Columns(Func):
5453    arg_types = {"this": True, "unpack": False}
5454
5455
5456# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
5457class Convert(Func):
5458    arg_types = {"this": True, "expression": True, "style": False}
5459
5460
5461class ConvertTimezone(Func):
5462    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
5463
5464
5465class GenerateSeries(Func):
5466    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
5467
5468
5469# Postgres' GENERATE_SERIES function returns a row set, i.e. it implicitly explodes when it's
5470# used in a projection, so this expression is a helper that facilitates transpilation to other
5471# dialects. For example, we'd generate UNNEST(GENERATE_SERIES(...)) in DuckDB
5472class ExplodingGenerateSeries(GenerateSeries):
5473    pass
5474
5475
5476class ArrayAgg(AggFunc):
5477    arg_types = {"this": True, "nulls_excluded": False}
5478
5479
5480class ArrayUniqueAgg(AggFunc):
5481    pass
5482
5483
5484class ArrayAll(Func):
5485    arg_types = {"this": True, "expression": True}
5486
5487
5488# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
5489class ArrayAny(Func):
5490    arg_types = {"this": True, "expression": True}
5491
5492
5493class ArrayConcat(Func):
5494    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5495    arg_types = {"this": True, "expressions": False}
5496    is_var_len_args = True
5497
5498
5499class ArrayConstructCompact(Func):
5500    arg_types = {"expressions": True}
5501    is_var_len_args = True
5502
5503
5504class ArrayContains(Binary, Func):
5505    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5506
5507
5508class ArrayContainsAll(Binary, Func):
5509    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5510
5511
5512class ArrayFilter(Func):
5513    arg_types = {"this": True, "expression": True}
5514    _sql_names = ["FILTER", "ARRAY_FILTER"]
5515
5516
5517class ArrayToString(Func):
5518    arg_types = {"this": True, "expression": True, "null": False}
5519    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5520
5521
5522# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5523class String(Func):
5524    arg_types = {"this": True, "zone": False}
5525
5526
5527class StringToArray(Func):
5528    arg_types = {"this": True, "expression": True, "null": False}
5529    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
5530
5531
5532class ArrayOverlaps(Binary, Func):
5533    pass
5534
5535
5536class ArraySize(Func):
5537    arg_types = {"this": True, "expression": False}
5538    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5539
5540
5541class ArraySort(Func):
5542    arg_types = {"this": True, "expression": False}
5543
5544
5545class ArraySum(Func):
5546    arg_types = {"this": True, "expression": False}
5547
5548
5549class ArrayUnionAgg(AggFunc):
5550    pass
5551
5552
5553class Avg(AggFunc):
5554    pass
5555
5556
5557class AnyValue(AggFunc):
5558    pass
5559
5560
5561class Lag(AggFunc):
5562    arg_types = {"this": True, "offset": False, "default": False}
5563
5564
5565class Lead(AggFunc):
5566    arg_types = {"this": True, "offset": False, "default": False}
5567
5568
5569# some dialects have a distinction between first and first_value, usually first is an aggregate func
5570# and first_value is a window func
5571class First(AggFunc):
5572    pass
5573
5574
5575class Last(AggFunc):
5576    pass
5577
5578
5579class FirstValue(AggFunc):
5580    pass
5581
5582
5583class LastValue(AggFunc):
5584    pass
5585
5586
5587class NthValue(AggFunc):
5588    arg_types = {"this": True, "offset": True}
5589
5590
5591class Case(Func):
5592    arg_types = {"this": False, "ifs": True, "default": False}
5593
5594    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5595        instance = maybe_copy(self, copy)
5596        instance.append(
5597            "ifs",
5598            If(
5599                this=maybe_parse(condition, copy=copy, **opts),
5600                true=maybe_parse(then, copy=copy, **opts),
5601            ),
5602        )
5603        return instance
5604
5605    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5606        instance = maybe_copy(self, copy)
5607        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5608        return instance
5609
5610
5611class Cast(Func):
5612    arg_types = {
5613        "this": True,
5614        "to": True,
5615        "format": False,
5616        "safe": False,
5617        "action": False,
5618        "default": False,
5619    }
5620
5621    @property
5622    def name(self) -> str:
5623        return self.this.name
5624
5625    @property
5626    def to(self) -> DataType:
5627        return self.args["to"]
5628
5629    @property
5630    def output_name(self) -> str:
5631        return self.name
5632
5633    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5634        """
5635        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5636        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5637        array<int> != array<float>.
5638
5639        Args:
5640            dtypes: the data types to compare this Cast's DataType to.
5641
5642        Returns:
5643            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5644        """
5645        return self.to.is_type(*dtypes)
5646
5647
5648class TryCast(Cast):
5649    pass
5650
5651
5652# https://clickhouse.com/docs/sql-reference/data-types/newjson#reading-json-paths-as-sub-columns
5653class JSONCast(Cast):
5654    pass
5655
5656
5657class Try(Func):
5658    pass
5659
5660
5661class CastToStrType(Func):
5662    arg_types = {"this": True, "to": True}
5663
5664
5665class Collate(Binary, Func):
5666    pass
5667
5668
5669class Ceil(Func):
5670    arg_types = {"this": True, "decimals": False, "to": False}
5671    _sql_names = ["CEIL", "CEILING"]
5672
5673
5674class Coalesce(Func):
5675    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5676    is_var_len_args = True
5677    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5678
5679
5680class Chr(Func):
5681    arg_types = {"expressions": True, "charset": False}
5682    is_var_len_args = True
5683    _sql_names = ["CHR", "CHAR"]
5684
5685
5686class Concat(Func):
5687    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5688    is_var_len_args = True
5689
5690
5691class ConcatWs(Concat):
5692    _sql_names = ["CONCAT_WS"]
5693
5694
5695class Contains(Func):
5696    arg_types = {"this": True, "expression": True}
5697
5698
5699# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5700class ConnectByRoot(Func):
5701    pass
5702
5703
5704class Count(AggFunc):
5705    arg_types = {"this": False, "expressions": False, "big_int": False}
5706    is_var_len_args = True
5707
5708
5709class CountIf(AggFunc):
5710    _sql_names = ["COUNT_IF", "COUNTIF"]
5711
5712
5713# cube root
5714class Cbrt(Func):
5715    pass
5716
5717
5718class CurrentDate(Func):
5719    arg_types = {"this": False}
5720
5721
5722class CurrentDatetime(Func):
5723    arg_types = {"this": False}
5724
5725
5726class CurrentTime(Func):
5727    arg_types = {"this": False}
5728
5729
5730class CurrentTimestamp(Func):
5731    arg_types = {"this": False, "sysdate": False}
5732
5733
5734class CurrentSchema(Func):
5735    arg_types = {"this": False}
5736
5737
5738class CurrentUser(Func):
5739    arg_types = {"this": False}
5740
5741
5742class DateAdd(Func, IntervalOp):
5743    arg_types = {"this": True, "expression": True, "unit": False}
5744
5745
5746class DateBin(Func, IntervalOp):
5747    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5748
5749
5750class DateSub(Func, IntervalOp):
5751    arg_types = {"this": True, "expression": True, "unit": False}
5752
5753
5754class DateDiff(Func, TimeUnit):
5755    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5756    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5757
5758
5759class DateTrunc(Func):
5760    arg_types = {"unit": True, "this": True, "zone": False}
5761
5762    def __init__(self, **args):
5763        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5764        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5765        unabbreviate = args.pop("unabbreviate", True)
5766
5767        unit = args.get("unit")
5768        if isinstance(unit, TimeUnit.VAR_LIKE):
5769            unit_name = unit.name.upper()
5770            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5771                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5772
5773            args["unit"] = Literal.string(unit_name)
5774        elif isinstance(unit, Week):
5775            unit.set("this", Literal.string(unit.this.name.upper()))
5776
5777        super().__init__(**args)
5778
5779    @property
5780    def unit(self) -> Expression:
5781        return self.args["unit"]
5782
5783
5784# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5785# expression can either be time_expr or time_zone
5786class Datetime(Func):
5787    arg_types = {"this": True, "expression": False}
5788
5789
5790class DatetimeAdd(Func, IntervalOp):
5791    arg_types = {"this": True, "expression": True, "unit": False}
5792
5793
5794class DatetimeSub(Func, IntervalOp):
5795    arg_types = {"this": True, "expression": True, "unit": False}
5796
5797
5798class DatetimeDiff(Func, TimeUnit):
5799    arg_types = {"this": True, "expression": True, "unit": False}
5800
5801
5802class DatetimeTrunc(Func, TimeUnit):
5803    arg_types = {"this": True, "unit": True, "zone": False}
5804
5805
5806class DayOfWeek(Func):
5807    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5808
5809
5810# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5811# ISO day of week function in duckdb is ISODOW
5812class DayOfWeekIso(Func):
5813    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5814
5815
5816class DayOfMonth(Func):
5817    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5818
5819
5820class DayOfYear(Func):
5821    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5822
5823
5824class ToDays(Func):
5825    pass
5826
5827
5828class WeekOfYear(Func):
5829    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5830
5831
5832class MonthsBetween(Func):
5833    arg_types = {"this": True, "expression": True, "roundoff": False}
5834
5835
5836class MakeInterval(Func):
5837    arg_types = {
5838        "year": False,
5839        "month": False,
5840        "day": False,
5841        "hour": False,
5842        "minute": False,
5843        "second": False,
5844    }
5845
5846
5847class LastDay(Func, TimeUnit):
5848    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5849    arg_types = {"this": True, "unit": False}
5850
5851
5852class Extract(Func):
5853    arg_types = {"this": True, "expression": True}
5854
5855
5856class Exists(Func, SubqueryPredicate):
5857    arg_types = {"this": True, "expression": False}
5858
5859
5860class Timestamp(Func):
5861    arg_types = {"this": False, "zone": False, "with_tz": False}
5862
5863
5864class TimestampAdd(Func, TimeUnit):
5865    arg_types = {"this": True, "expression": True, "unit": False}
5866
5867
5868class TimestampSub(Func, TimeUnit):
5869    arg_types = {"this": True, "expression": True, "unit": False}
5870
5871
5872class TimestampDiff(Func, TimeUnit):
5873    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5874    arg_types = {"this": True, "expression": True, "unit": False}
5875
5876
5877class TimestampTrunc(Func, TimeUnit):
5878    arg_types = {"this": True, "unit": True, "zone": False}
5879
5880
5881class TimeAdd(Func, TimeUnit):
5882    arg_types = {"this": True, "expression": True, "unit": False}
5883
5884
5885class TimeSub(Func, TimeUnit):
5886    arg_types = {"this": True, "expression": True, "unit": False}
5887
5888
5889class TimeDiff(Func, TimeUnit):
5890    arg_types = {"this": True, "expression": True, "unit": False}
5891
5892
5893class TimeTrunc(Func, TimeUnit):
5894    arg_types = {"this": True, "unit": True, "zone": False}
5895
5896
5897class DateFromParts(Func):
5898    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5899    arg_types = {"year": True, "month": True, "day": True}
5900
5901
5902class TimeFromParts(Func):
5903    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5904    arg_types = {
5905        "hour": True,
5906        "min": True,
5907        "sec": True,
5908        "nano": False,
5909        "fractions": False,
5910        "precision": False,
5911    }
5912
5913
5914class DateStrToDate(Func):
5915    pass
5916
5917
5918class DateToDateStr(Func):
5919    pass
5920
5921
5922class DateToDi(Func):
5923    pass
5924
5925
5926# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5927class Date(Func):
5928    arg_types = {"this": False, "zone": False, "expressions": False}
5929    is_var_len_args = True
5930
5931
5932class Day(Func):
5933    pass
5934
5935
5936class Decode(Func):
5937    arg_types = {"this": True, "charset": True, "replace": False}
5938
5939
5940class DiToDate(Func):
5941    pass
5942
5943
5944class Encode(Func):
5945    arg_types = {"this": True, "charset": True}
5946
5947
5948class Exp(Func):
5949    pass
5950
5951
5952# https://docs.snowflake.com/en/sql-reference/functions/flatten
5953class Explode(Func, UDTF):
5954    arg_types = {"this": True, "expressions": False}
5955    is_var_len_args = True
5956
5957
5958# https://spark.apache.org/docs/latest/api/sql/#inline
5959class Inline(Func):
5960    pass
5961
5962
5963class ExplodeOuter(Explode):
5964    pass
5965
5966
5967class Posexplode(Explode):
5968    pass
5969
5970
5971class PosexplodeOuter(Posexplode, ExplodeOuter):
5972    pass
5973
5974
5975class Unnest(Func, UDTF):
5976    arg_types = {
5977        "expressions": True,
5978        "alias": False,
5979        "offset": False,
5980        "explode_array": False,
5981    }
5982
5983    @property
5984    def selects(self) -> t.List[Expression]:
5985        columns = super().selects
5986        offset = self.args.get("offset")
5987        if offset:
5988            columns = columns + [to_identifier("offset") if offset is True else offset]
5989        return columns
5990
5991
5992class Floor(Func):
5993    arg_types = {"this": True, "decimals": False, "to": False}
5994
5995
5996class FromBase64(Func):
5997    pass
5998
5999
6000class FeaturesAtTime(Func):
6001    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
6002
6003
6004class ToBase64(Func):
6005    pass
6006
6007
6008# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
6009class FromISO8601Timestamp(Func):
6010    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
6011
6012
6013class GapFill(Func):
6014    arg_types = {
6015        "this": True,
6016        "ts_column": True,
6017        "bucket_width": True,
6018        "partitioning_columns": False,
6019        "value_columns": False,
6020        "origin": False,
6021        "ignore_nulls": False,
6022    }
6023
6024
6025# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
6026class GenerateDateArray(Func):
6027    arg_types = {"start": True, "end": True, "step": False}
6028
6029
6030# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
6031class GenerateTimestampArray(Func):
6032    arg_types = {"start": True, "end": True, "step": True}
6033
6034
6035class Greatest(Func):
6036    arg_types = {"this": True, "expressions": False}
6037    is_var_len_args = True
6038
6039
6040# Trino's `ON OVERFLOW TRUNCATE [filler_string] {WITH | WITHOUT} COUNT`
6041# https://trino.io/docs/current/functions/aggregate.html#listagg
6042class OverflowTruncateBehavior(Expression):
6043    arg_types = {"this": False, "with_count": True}
6044
6045
6046class GroupConcat(AggFunc):
6047    arg_types = {"this": True, "separator": False, "on_overflow": False}
6048
6049
6050class Hex(Func):
6051    pass
6052
6053
6054class LowerHex(Hex):
6055    pass
6056
6057
6058class And(Connector, Func):
6059    pass
6060
6061
6062class Or(Connector, Func):
6063    pass
6064
6065
6066class Xor(Connector, Func):
6067    arg_types = {"this": False, "expression": False, "expressions": False}
6068
6069
6070class If(Func):
6071    arg_types = {"this": True, "true": True, "false": False}
6072    _sql_names = ["IF", "IIF"]
6073
6074
6075class Nullif(Func):
6076    arg_types = {"this": True, "expression": True}
6077
6078
6079class Initcap(Func):
6080    arg_types = {"this": True, "expression": False}
6081
6082
6083class IsAscii(Func):
6084    pass
6085
6086
6087class IsNan(Func):
6088    _sql_names = ["IS_NAN", "ISNAN"]
6089
6090
6091# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#int64_for_json
6092class Int64(Func):
6093    pass
6094
6095
6096class IsInf(Func):
6097    _sql_names = ["IS_INF", "ISINF"]
6098
6099
6100# https://www.postgresql.org/docs/current/functions-json.html
6101class JSON(Expression):
6102    arg_types = {"this": False, "with": False, "unique": False}
6103
6104
6105class JSONPath(Expression):
6106    arg_types = {"expressions": True, "escape": False}
6107
6108    @property
6109    def output_name(self) -> str:
6110        last_segment = self.expressions[-1].this
6111        return last_segment if isinstance(last_segment, str) else ""
6112
6113
6114class JSONPathPart(Expression):
6115    arg_types = {}
6116
6117
6118class JSONPathFilter(JSONPathPart):
6119    arg_types = {"this": True}
6120
6121
6122class JSONPathKey(JSONPathPart):
6123    arg_types = {"this": True}
6124
6125
6126class JSONPathRecursive(JSONPathPart):
6127    arg_types = {"this": False}
6128
6129
6130class JSONPathRoot(JSONPathPart):
6131    pass
6132
6133
6134class JSONPathScript(JSONPathPart):
6135    arg_types = {"this": True}
6136
6137
6138class JSONPathSlice(JSONPathPart):
6139    arg_types = {"start": False, "end": False, "step": False}
6140
6141
6142class JSONPathSelector(JSONPathPart):
6143    arg_types = {"this": True}
6144
6145
6146class JSONPathSubscript(JSONPathPart):
6147    arg_types = {"this": True}
6148
6149
6150class JSONPathUnion(JSONPathPart):
6151    arg_types = {"expressions": True}
6152
6153
6154class JSONPathWildcard(JSONPathPart):
6155    pass
6156
6157
6158class FormatJson(Expression):
6159    pass
6160
6161
6162class JSONKeyValue(Expression):
6163    arg_types = {"this": True, "expression": True}
6164
6165
6166class JSONObject(Func):
6167    arg_types = {
6168        "expressions": False,
6169        "null_handling": False,
6170        "unique_keys": False,
6171        "return_type": False,
6172        "encoding": False,
6173    }
6174
6175
6176class JSONObjectAgg(AggFunc):
6177    arg_types = {
6178        "expressions": False,
6179        "null_handling": False,
6180        "unique_keys": False,
6181        "return_type": False,
6182        "encoding": False,
6183    }
6184
6185
6186# https://www.postgresql.org/docs/9.5/functions-aggregate.html
6187class JSONBObjectAgg(AggFunc):
6188    arg_types = {"this": True, "expression": True}
6189
6190
6191# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
6192class JSONArray(Func):
6193    arg_types = {
6194        "expressions": True,
6195        "null_handling": False,
6196        "return_type": False,
6197        "strict": False,
6198    }
6199
6200
6201# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
6202class JSONArrayAgg(Func):
6203    arg_types = {
6204        "this": True,
6205        "order": False,
6206        "null_handling": False,
6207        "return_type": False,
6208        "strict": False,
6209    }
6210
6211
6212class JSONExists(Func):
6213    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
6214
6215
6216# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6217# Note: parsing of JSON column definitions is currently incomplete.
6218class JSONColumnDef(Expression):
6219    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
6220
6221
6222class JSONSchema(Expression):
6223    arg_types = {"expressions": True}
6224
6225
6226# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
6227class JSONValue(Expression):
6228    arg_types = {
6229        "this": True,
6230        "path": True,
6231        "returning": False,
6232        "on_condition": False,
6233    }
6234
6235
6236class JSONValueArray(Func):
6237    arg_types = {"this": True, "expression": False}
6238
6239
6240# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6241class JSONTable(Func):
6242    arg_types = {
6243        "this": True,
6244        "schema": True,
6245        "path": False,
6246        "error_handling": False,
6247        "empty_handling": False,
6248    }
6249
6250
6251# https://docs.snowflake.com/en/sql-reference/functions/object_insert
6252class ObjectInsert(Func):
6253    arg_types = {
6254        "this": True,
6255        "key": True,
6256        "value": True,
6257        "update_flag": False,
6258    }
6259
6260
6261class OpenJSONColumnDef(Expression):
6262    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
6263
6264
6265class OpenJSON(Func):
6266    arg_types = {"this": True, "path": False, "expressions": False}
6267
6268
6269class JSONBContains(Binary, Func):
6270    _sql_names = ["JSONB_CONTAINS"]
6271
6272
6273class JSONBExists(Func):
6274    arg_types = {"this": True, "path": True}
6275    _sql_names = ["JSONB_EXISTS"]
6276
6277
6278class JSONExtract(Binary, Func):
6279    arg_types = {
6280        "this": True,
6281        "expression": True,
6282        "only_json_types": False,
6283        "expressions": False,
6284        "variant_extract": False,
6285        "json_query": False,
6286        "option": False,
6287        "quote": False,
6288        "on_condition": False,
6289    }
6290    _sql_names = ["JSON_EXTRACT"]
6291    is_var_len_args = True
6292
6293    @property
6294    def output_name(self) -> str:
6295        return self.expression.output_name if not self.expressions else ""
6296
6297
6298# https://trino.io/docs/current/functions/json.html#json-query
6299class JSONExtractQuote(Expression):
6300    arg_types = {
6301        "option": True,
6302        "scalar": False,
6303    }
6304
6305
6306class JSONExtractArray(Func):
6307    arg_types = {"this": True, "expression": False}
6308    _sql_names = ["JSON_EXTRACT_ARRAY"]
6309
6310
6311class JSONExtractScalar(Binary, Func):
6312    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6313    _sql_names = ["JSON_EXTRACT_SCALAR"]
6314    is_var_len_args = True
6315
6316    @property
6317    def output_name(self) -> str:
6318        return self.expression.output_name
6319
6320
6321class JSONBExtract(Binary, Func):
6322    _sql_names = ["JSONB_EXTRACT"]
6323
6324
6325class JSONBExtractScalar(Binary, Func):
6326    _sql_names = ["JSONB_EXTRACT_SCALAR"]
6327
6328
6329class JSONFormat(Func):
6330    arg_types = {"this": False, "options": False, "is_json": False}
6331    _sql_names = ["JSON_FORMAT"]
6332
6333
6334# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
6335class JSONArrayContains(Binary, Predicate, Func):
6336    _sql_names = ["JSON_ARRAY_CONTAINS"]
6337
6338
6339class ParseJSON(Func):
6340    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6341    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6342    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6343    arg_types = {"this": True, "expression": False, "safe": False}
6344
6345
6346class Least(Func):
6347    arg_types = {"this": True, "expressions": False}
6348    is_var_len_args = True
6349
6350
6351class Left(Func):
6352    arg_types = {"this": True, "expression": True}
6353
6354
6355class Right(Func):
6356    arg_types = {"this": True, "expression": True}
6357
6358
6359class Length(Func):
6360    arg_types = {"this": True, "binary": False, "encoding": False}
6361    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
6362
6363
6364class Levenshtein(Func):
6365    arg_types = {
6366        "this": True,
6367        "expression": False,
6368        "ins_cost": False,
6369        "del_cost": False,
6370        "sub_cost": False,
6371        "max_dist": False,
6372    }
6373
6374
6375class Ln(Func):
6376    pass
6377
6378
6379class Log(Func):
6380    arg_types = {"this": True, "expression": False}
6381
6382
6383class LogicalOr(AggFunc):
6384    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
6385
6386
6387class LogicalAnd(AggFunc):
6388    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
6389
6390
6391class Lower(Func):
6392    _sql_names = ["LOWER", "LCASE"]
6393
6394
6395class Map(Func):
6396    arg_types = {"keys": False, "values": False}
6397
6398    @property
6399    def keys(self) -> t.List[Expression]:
6400        keys = self.args.get("keys")
6401        return keys.expressions if keys else []
6402
6403    @property
6404    def values(self) -> t.List[Expression]:
6405        values = self.args.get("values")
6406        return values.expressions if values else []
6407
6408
6409# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
6410class ToMap(Func):
6411    pass
6412
6413
6414class MapFromEntries(Func):
6415    pass
6416
6417
6418# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
6419class ScopeResolution(Expression):
6420    arg_types = {"this": False, "expression": True}
6421
6422
6423class Stream(Expression):
6424    pass
6425
6426
6427class StarMap(Func):
6428    pass
6429
6430
6431class VarMap(Func):
6432    arg_types = {"keys": True, "values": True}
6433    is_var_len_args = True
6434
6435    @property
6436    def keys(self) -> t.List[Expression]:
6437        return self.args["keys"].expressions
6438
6439    @property
6440    def values(self) -> t.List[Expression]:
6441        return self.args["values"].expressions
6442
6443
6444# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
6445class MatchAgainst(Func):
6446    arg_types = {"this": True, "expressions": True, "modifier": False}
6447
6448
6449class Max(AggFunc):
6450    arg_types = {"this": True, "expressions": False}
6451    is_var_len_args = True
6452
6453
6454class MD5(Func):
6455    _sql_names = ["MD5"]
6456
6457
6458# Represents the variant of the MD5 function that returns a binary value
6459class MD5Digest(Func):
6460    _sql_names = ["MD5_DIGEST"]
6461
6462
6463class Median(AggFunc):
6464    pass
6465
6466
6467class Min(AggFunc):
6468    arg_types = {"this": True, "expressions": False}
6469    is_var_len_args = True
6470
6471
6472class Month(Func):
6473    pass
6474
6475
6476class AddMonths(Func):
6477    arg_types = {"this": True, "expression": True}
6478
6479
6480class Nvl2(Func):
6481    arg_types = {"this": True, "true": True, "false": False}
6482
6483
6484class Normalize(Func):
6485    arg_types = {"this": True, "form": False}
6486
6487
6488class Overlay(Func):
6489    arg_types = {"this": True, "expression": True, "from": True, "for": False}
6490
6491
6492# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
6493class Predict(Func):
6494    arg_types = {"this": True, "expression": True, "params_struct": False}
6495
6496
6497class Pow(Binary, Func):
6498    _sql_names = ["POWER", "POW"]
6499
6500
6501class PercentileCont(AggFunc):
6502    arg_types = {"this": True, "expression": False}
6503
6504
6505class PercentileDisc(AggFunc):
6506    arg_types = {"this": True, "expression": False}
6507
6508
6509class Quantile(AggFunc):
6510    arg_types = {"this": True, "quantile": True}
6511
6512
6513class ApproxQuantile(Quantile):
6514    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
6515
6516
6517class Quarter(Func):
6518    pass
6519
6520
6521# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
6522# teradata lower and upper bounds
6523class Rand(Func):
6524    _sql_names = ["RAND", "RANDOM"]
6525    arg_types = {"this": False, "lower": False, "upper": False}
6526
6527
6528class Randn(Func):
6529    arg_types = {"this": False}
6530
6531
6532class RangeN(Func):
6533    arg_types = {"this": True, "expressions": True, "each": False}
6534
6535
6536class ReadCSV(Func):
6537    _sql_names = ["READ_CSV"]
6538    is_var_len_args = True
6539    arg_types = {"this": True, "expressions": False}
6540
6541
6542class Reduce(Func):
6543    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
6544
6545
6546class RegexpExtract(Func):
6547    arg_types = {
6548        "this": True,
6549        "expression": True,
6550        "position": False,
6551        "occurrence": False,
6552        "parameters": False,
6553        "group": False,
6554    }
6555
6556
6557class RegexpExtractAll(Func):
6558    arg_types = {
6559        "this": True,
6560        "expression": True,
6561        "position": False,
6562        "occurrence": False,
6563        "parameters": False,
6564        "group": False,
6565    }
6566
6567
6568class RegexpReplace(Func):
6569    arg_types = {
6570        "this": True,
6571        "expression": True,
6572        "replacement": False,
6573        "position": False,
6574        "occurrence": False,
6575        "modifiers": False,
6576    }
6577
6578
6579class RegexpLike(Binary, Func):
6580    arg_types = {"this": True, "expression": True, "flag": False}
6581
6582
6583class RegexpILike(Binary, Func):
6584    arg_types = {"this": True, "expression": True, "flag": False}
6585
6586
6587# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6588# limit is the number of times a pattern is applied
6589class RegexpSplit(Func):
6590    arg_types = {"this": True, "expression": True, "limit": False}
6591
6592
6593class Repeat(Func):
6594    arg_types = {"this": True, "times": True}
6595
6596
6597# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6598# tsql third argument function == trunctaion if not 0
6599class Round(Func):
6600    arg_types = {"this": True, "decimals": False, "truncate": False}
6601
6602
6603class RowNumber(Func):
6604    arg_types = {"this": False}
6605
6606
6607class SafeDivide(Func):
6608    arg_types = {"this": True, "expression": True}
6609
6610
6611class SHA(Func):
6612    _sql_names = ["SHA", "SHA1"]
6613
6614
6615class SHA2(Func):
6616    _sql_names = ["SHA2"]
6617    arg_types = {"this": True, "length": False}
6618
6619
6620class Sign(Func):
6621    _sql_names = ["SIGN", "SIGNUM"]
6622
6623
6624class SortArray(Func):
6625    arg_types = {"this": True, "asc": False}
6626
6627
6628class Split(Func):
6629    arg_types = {"this": True, "expression": True, "limit": False}
6630
6631
6632# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split_part.html
6633class SplitPart(Func):
6634    arg_types = {"this": True, "delimiter": True, "part_index": True}
6635
6636
6637# Start may be omitted in the case of postgres
6638# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6639class Substring(Func):
6640    _sql_names = ["SUBSTRING", "SUBSTR"]
6641    arg_types = {"this": True, "start": False, "length": False}
6642
6643
6644class StandardHash(Func):
6645    arg_types = {"this": True, "expression": False}
6646
6647
6648class StartsWith(Func):
6649    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6650    arg_types = {"this": True, "expression": True}
6651
6652
6653class StrPosition(Func):
6654    arg_types = {
6655        "this": True,
6656        "substr": True,
6657        "position": False,
6658        "occurrence": False,
6659    }
6660
6661
6662class StrToDate(Func):
6663    arg_types = {"this": True, "format": False, "safe": False}
6664
6665
6666class StrToTime(Func):
6667    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6668
6669
6670# Spark allows unix_timestamp()
6671# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6672class StrToUnix(Func):
6673    arg_types = {"this": False, "format": False}
6674
6675
6676# https://prestodb.io/docs/current/functions/string.html
6677# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6678class StrToMap(Func):
6679    arg_types = {
6680        "this": True,
6681        "pair_delim": False,
6682        "key_value_delim": False,
6683        "duplicate_resolution_callback": False,
6684    }
6685
6686
6687class NumberToStr(Func):
6688    arg_types = {"this": True, "format": True, "culture": False}
6689
6690
6691class FromBase(Func):
6692    arg_types = {"this": True, "expression": True}
6693
6694
6695class Struct(Func):
6696    arg_types = {"expressions": False}
6697    is_var_len_args = True
6698
6699
6700class StructExtract(Func):
6701    arg_types = {"this": True, "expression": True}
6702
6703
6704# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6705# https://docs.snowflake.com/en/sql-reference/functions/insert
6706class Stuff(Func):
6707    _sql_names = ["STUFF", "INSERT"]
6708    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6709
6710
6711class Sum(AggFunc):
6712    pass
6713
6714
6715class Sqrt(Func):
6716    pass
6717
6718
6719class Stddev(AggFunc):
6720    _sql_names = ["STDDEV", "STDEV"]
6721
6722
6723class StddevPop(AggFunc):
6724    pass
6725
6726
6727class StddevSamp(AggFunc):
6728    pass
6729
6730
6731# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6732class Time(Func):
6733    arg_types = {"this": False, "zone": False}
6734
6735
6736class TimeToStr(Func):
6737    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6738
6739
6740class TimeToTimeStr(Func):
6741    pass
6742
6743
6744class TimeToUnix(Func):
6745    pass
6746
6747
6748class TimeStrToDate(Func):
6749    pass
6750
6751
6752class TimeStrToTime(Func):
6753    arg_types = {"this": True, "zone": False}
6754
6755
6756class TimeStrToUnix(Func):
6757    pass
6758
6759
6760class Trim(Func):
6761    arg_types = {
6762        "this": True,
6763        "expression": False,
6764        "position": False,
6765        "collation": False,
6766    }
6767
6768
6769class TsOrDsAdd(Func, TimeUnit):
6770    # return_type is used to correctly cast the arguments of this expression when transpiling it
6771    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6772
6773    @property
6774    def return_type(self) -> DataType:
6775        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
6776
6777
6778class TsOrDsDiff(Func, TimeUnit):
6779    arg_types = {"this": True, "expression": True, "unit": False}
6780
6781
6782class TsOrDsToDateStr(Func):
6783    pass
6784
6785
6786class TsOrDsToDate(Func):
6787    arg_types = {"this": True, "format": False, "safe": False}
6788
6789
6790class TsOrDsToDatetime(Func):
6791    pass
6792
6793
6794class TsOrDsToTime(Func):
6795    arg_types = {"this": True, "format": False, "safe": False}
6796
6797
6798class TsOrDsToTimestamp(Func):
6799    pass
6800
6801
6802class TsOrDiToDi(Func):
6803    pass
6804
6805
6806class Unhex(Func):
6807    arg_types = {"this": True, "expression": False}
6808
6809
6810class Unicode(Func):
6811    pass
6812
6813
6814# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
6815class UnixDate(Func):
6816    pass
6817
6818
6819class UnixToStr(Func):
6820    arg_types = {"this": True, "format": False}
6821
6822
6823# https://prestodb.io/docs/current/functions/datetime.html
6824# presto has weird zone/hours/minutes
6825class UnixToTime(Func):
6826    arg_types = {
6827        "this": True,
6828        "scale": False,
6829        "zone": False,
6830        "hours": False,
6831        "minutes": False,
6832        "format": False,
6833    }
6834
6835    SECONDS = Literal.number(0)
6836    DECIS = Literal.number(1)
6837    CENTIS = Literal.number(2)
6838    MILLIS = Literal.number(3)
6839    DECIMILLIS = Literal.number(4)
6840    CENTIMILLIS = Literal.number(5)
6841    MICROS = Literal.number(6)
6842    DECIMICROS = Literal.number(7)
6843    CENTIMICROS = Literal.number(8)
6844    NANOS = Literal.number(9)
6845
6846
6847class UnixToTimeStr(Func):
6848    pass
6849
6850
6851class UnixSeconds(Func):
6852    pass
6853
6854
6855class Uuid(Func):
6856    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6857
6858    arg_types = {"this": False, "name": False}
6859
6860
6861class TimestampFromParts(Func):
6862    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6863    arg_types = {
6864        "year": True,
6865        "month": True,
6866        "day": True,
6867        "hour": True,
6868        "min": True,
6869        "sec": True,
6870        "nano": False,
6871        "zone": False,
6872        "milli": False,
6873    }
6874
6875
6876class Upper(Func):
6877    _sql_names = ["UPPER", "UCASE"]
6878
6879
6880class Corr(Binary, AggFunc):
6881    pass
6882
6883
6884class Variance(AggFunc):
6885    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6886
6887
6888class VariancePop(AggFunc):
6889    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6890
6891
6892class CovarSamp(Binary, AggFunc):
6893    pass
6894
6895
6896class CovarPop(Binary, AggFunc):
6897    pass
6898
6899
6900class Week(Func):
6901    arg_types = {"this": True, "mode": False}
6902
6903
6904class XMLElement(Func):
6905    _sql_names = ["XMLELEMENT"]
6906    arg_types = {"this": True, "expressions": False}
6907
6908
6909class XMLTable(Func):
6910    arg_types = {
6911        "this": True,
6912        "namespaces": False,
6913        "passing": False,
6914        "columns": False,
6915        "by_ref": False,
6916    }
6917
6918
6919class XMLNamespace(Expression):
6920    pass
6921
6922
6923class Year(Func):
6924    pass
6925
6926
6927class Use(Expression):
6928    arg_types = {"this": False, "expressions": False, "kind": False}
6929
6930
6931class Merge(DML):
6932    arg_types = {
6933        "this": True,
6934        "using": True,
6935        "on": True,
6936        "whens": True,
6937        "with": False,
6938        "returning": False,
6939    }
6940
6941
6942class When(Expression):
6943    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6944
6945
6946class Whens(Expression):
6947    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6948
6949    arg_types = {"expressions": True}
6950
6951
6952# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
6953# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
6954class NextValueFor(Func):
6955    arg_types = {"this": True, "order": False}
6956
6957
6958# Refers to a trailing semi-colon. This is only used to preserve trailing comments
6959# select 1; -- my comment
6960class Semicolon(Expression):
6961    arg_types = {}
6962
6963
6964def _norm_arg(arg):
6965    return arg.lower() if type(arg) is str else arg
6966
6967
6968ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
6969FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
6970
6971JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
6972
6973PERCENTILES = (PercentileCont, PercentileDisc)
6974
6975
6976# Helpers
6977@t.overload
6978def maybe_parse(
6979    sql_or_expression: ExpOrStr,
6980    *,
6981    into: t.Type[E],
6982    dialect: DialectType = None,
6983    prefix: t.Optional[str] = None,
6984    copy: bool = False,
6985    **opts,
6986) -> E: ...
6987
6988
6989@t.overload
6990def maybe_parse(
6991    sql_or_expression: str | E,
6992    *,
6993    into: t.Optional[IntoType] = None,
6994    dialect: DialectType = None,
6995    prefix: t.Optional[str] = None,
6996    copy: bool = False,
6997    **opts,
6998) -> E: ...
6999
7000
7001def maybe_parse(
7002    sql_or_expression: ExpOrStr,
7003    *,
7004    into: t.Optional[IntoType] = None,
7005    dialect: DialectType = None,
7006    prefix: t.Optional[str] = None,
7007    copy: bool = False,
7008    **opts,
7009) -> Expression:
7010    """Gracefully handle a possible string or expression.
7011
7012    Example:
7013        >>> maybe_parse("1")
7014        Literal(this=1, is_string=False)
7015        >>> maybe_parse(to_identifier("x"))
7016        Identifier(this=x, quoted=False)
7017
7018    Args:
7019        sql_or_expression: the SQL code string or an expression
7020        into: the SQLGlot Expression to parse into
7021        dialect: the dialect used to parse the input expressions (in the case that an
7022            input expression is a SQL string).
7023        prefix: a string to prefix the sql with before it gets parsed
7024            (automatically includes a space)
7025        copy: whether to copy the expression.
7026        **opts: other options to use to parse the input expressions (again, in the case
7027            that an input expression is a SQL string).
7028
7029    Returns:
7030        Expression: the parsed or given expression.
7031    """
7032    if isinstance(sql_or_expression, Expression):
7033        if copy:
7034            return sql_or_expression.copy()
7035        return sql_or_expression
7036
7037    if sql_or_expression is None:
7038        raise ParseError("SQL cannot be None")
7039
7040    import sqlglot
7041
7042    sql = str(sql_or_expression)
7043    if prefix:
7044        sql = f"{prefix} {sql}"
7045
7046    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
7047
7048
7049@t.overload
7050def maybe_copy(instance: None, copy: bool = True) -> None: ...
7051
7052
7053@t.overload
7054def maybe_copy(instance: E, copy: bool = True) -> E: ...
7055
7056
7057def maybe_copy(instance, copy=True):
7058    return instance.copy() if copy and instance else instance
7059
7060
7061def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str:
7062    """Generate a textual representation of an Expression tree"""
7063    indent = "\n" + ("  " * (level + 1))
7064    delim = f",{indent}"
7065
7066    if isinstance(node, Expression):
7067        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
7068
7069        if (node.type or verbose) and not isinstance(node, DataType):
7070            args["_type"] = node.type
7071        if node.comments or verbose:
7072            args["_comments"] = node.comments
7073
7074        if verbose:
7075            args["_id"] = id(node)
7076
7077        # Inline leaves for a more compact representation
7078        if node.is_leaf():
7079            indent = ""
7080            delim = ", "
7081
7082        repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted)
7083        items = delim.join(
7084            [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()]
7085        )
7086        return f"{node.__class__.__name__}({indent}{items})"
7087
7088    if isinstance(node, list):
7089        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
7090        items = f"{indent}{items}" if items else ""
7091        return f"[{items}]"
7092
7093    # We use the representation of the string to avoid stripping out important whitespace
7094    if repr_str and isinstance(node, str):
7095        node = repr(node)
7096
7097    # Indent multiline strings to match the current level
7098    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
7099
7100
7101def _is_wrong_expression(expression, into):
7102    return isinstance(expression, Expression) and not isinstance(expression, into)
7103
7104
7105def _apply_builder(
7106    expression,
7107    instance,
7108    arg,
7109    copy=True,
7110    prefix=None,
7111    into=None,
7112    dialect=None,
7113    into_arg="this",
7114    **opts,
7115):
7116    if _is_wrong_expression(expression, into):
7117        expression = into(**{into_arg: expression})
7118    instance = maybe_copy(instance, copy)
7119    expression = maybe_parse(
7120        sql_or_expression=expression,
7121        prefix=prefix,
7122        into=into,
7123        dialect=dialect,
7124        **opts,
7125    )
7126    instance.set(arg, expression)
7127    return instance
7128
7129
7130def _apply_child_list_builder(
7131    *expressions,
7132    instance,
7133    arg,
7134    append=True,
7135    copy=True,
7136    prefix=None,
7137    into=None,
7138    dialect=None,
7139    properties=None,
7140    **opts,
7141):
7142    instance = maybe_copy(instance, copy)
7143    parsed = []
7144    properties = {} if properties is None else properties
7145
7146    for expression in expressions:
7147        if expression is not None:
7148            if _is_wrong_expression(expression, into):
7149                expression = into(expressions=[expression])
7150
7151            expression = maybe_parse(
7152                expression,
7153                into=into,
7154                dialect=dialect,
7155                prefix=prefix,
7156                **opts,
7157            )
7158            for k, v in expression.args.items():
7159                if k == "expressions":
7160                    parsed.extend(v)
7161                else:
7162                    properties[k] = v
7163
7164    existing = instance.args.get(arg)
7165    if append and existing:
7166        parsed = existing.expressions + parsed
7167
7168    child = into(expressions=parsed)
7169    for k, v in properties.items():
7170        child.set(k, v)
7171    instance.set(arg, child)
7172
7173    return instance
7174
7175
7176def _apply_list_builder(
7177    *expressions,
7178    instance,
7179    arg,
7180    append=True,
7181    copy=True,
7182    prefix=None,
7183    into=None,
7184    dialect=None,
7185    **opts,
7186):
7187    inst = maybe_copy(instance, copy)
7188
7189    expressions = [
7190        maybe_parse(
7191            sql_or_expression=expression,
7192            into=into,
7193            prefix=prefix,
7194            dialect=dialect,
7195            **opts,
7196        )
7197        for expression in expressions
7198        if expression is not None
7199    ]
7200
7201    existing_expressions = inst.args.get(arg)
7202    if append and existing_expressions:
7203        expressions = existing_expressions + expressions
7204
7205    inst.set(arg, expressions)
7206    return inst
7207
7208
7209def _apply_conjunction_builder(
7210    *expressions,
7211    instance,
7212    arg,
7213    into=None,
7214    append=True,
7215    copy=True,
7216    dialect=None,
7217    **opts,
7218):
7219    expressions = [exp for exp in expressions if exp is not None and exp != ""]
7220    if not expressions:
7221        return instance
7222
7223    inst = maybe_copy(instance, copy)
7224
7225    existing = inst.args.get(arg)
7226    if append and existing is not None:
7227        expressions = [existing.this if into else existing] + list(expressions)
7228
7229    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
7230
7231    inst.set(arg, into(this=node) if into else node)
7232    return inst
7233
7234
7235def _apply_cte_builder(
7236    instance: E,
7237    alias: ExpOrStr,
7238    as_: ExpOrStr,
7239    recursive: t.Optional[bool] = None,
7240    materialized: t.Optional[bool] = None,
7241    append: bool = True,
7242    dialect: DialectType = None,
7243    copy: bool = True,
7244    scalar: bool = False,
7245    **opts,
7246) -> E:
7247    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
7248    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
7249    if scalar and not isinstance(as_expression, Subquery):
7250        # scalar CTE must be wrapped in a subquery
7251        as_expression = Subquery(this=as_expression)
7252    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
7253    return _apply_child_list_builder(
7254        cte,
7255        instance=instance,
7256        arg="with",
7257        append=append,
7258        copy=copy,
7259        into=With,
7260        properties={"recursive": recursive or False},
7261    )
7262
7263
7264def _combine(
7265    expressions: t.Sequence[t.Optional[ExpOrStr]],
7266    operator: t.Type[Connector],
7267    dialect: DialectType = None,
7268    copy: bool = True,
7269    wrap: bool = True,
7270    **opts,
7271) -> Expression:
7272    conditions = [
7273        condition(expression, dialect=dialect, copy=copy, **opts)
7274        for expression in expressions
7275        if expression is not None
7276    ]
7277
7278    this, *rest = conditions
7279    if rest and wrap:
7280        this = _wrap(this, Connector)
7281    for expression in rest:
7282        this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression)
7283
7284    return this
7285
7286
7287@t.overload
7288def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
7289
7290
7291@t.overload
7292def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
7293
7294
7295def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
7296    return Paren(this=expression) if isinstance(expression, kind) else expression
7297
7298
7299def _apply_set_operation(
7300    *expressions: ExpOrStr,
7301    set_operation: t.Type[S],
7302    distinct: bool = True,
7303    dialect: DialectType = None,
7304    copy: bool = True,
7305    **opts,
7306) -> S:
7307    return reduce(
7308        lambda x, y: set_operation(this=x, expression=y, distinct=distinct),
7309        (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7310    )
7311
7312
7313def union(
7314    *expressions: ExpOrStr,
7315    distinct: bool = True,
7316    dialect: DialectType = None,
7317    copy: bool = True,
7318    **opts,
7319) -> Union:
7320    """
7321    Initializes a syntax tree for the `UNION` operation.
7322
7323    Example:
7324        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7325        'SELECT * FROM foo UNION SELECT * FROM bla'
7326
7327    Args:
7328        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7329            If `Expression` instances are passed, they will be used as-is.
7330        distinct: set the DISTINCT flag if and only if this is true.
7331        dialect: the dialect used to parse the input expression.
7332        copy: whether to copy the expression.
7333        opts: other options to use to parse the input expressions.
7334
7335    Returns:
7336        The new Union instance.
7337    """
7338    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7339    return _apply_set_operation(
7340        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7341    )
7342
7343
7344def intersect(
7345    *expressions: ExpOrStr,
7346    distinct: bool = True,
7347    dialect: DialectType = None,
7348    copy: bool = True,
7349    **opts,
7350) -> Intersect:
7351    """
7352    Initializes a syntax tree for the `INTERSECT` operation.
7353
7354    Example:
7355        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7356        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7357
7358    Args:
7359        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7360            If `Expression` instances are passed, they will be used as-is.
7361        distinct: set the DISTINCT flag if and only if this is true.
7362        dialect: the dialect used to parse the input expression.
7363        copy: whether to copy the expression.
7364        opts: other options to use to parse the input expressions.
7365
7366    Returns:
7367        The new Intersect instance.
7368    """
7369    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7370    return _apply_set_operation(
7371        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7372    )
7373
7374
7375def except_(
7376    *expressions: ExpOrStr,
7377    distinct: bool = True,
7378    dialect: DialectType = None,
7379    copy: bool = True,
7380    **opts,
7381) -> Except:
7382    """
7383    Initializes a syntax tree for the `EXCEPT` operation.
7384
7385    Example:
7386        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7387        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7388
7389    Args:
7390        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7391            If `Expression` instances are passed, they will be used as-is.
7392        distinct: set the DISTINCT flag if and only if this is true.
7393        dialect: the dialect used to parse the input expression.
7394        copy: whether to copy the expression.
7395        opts: other options to use to parse the input expressions.
7396
7397    Returns:
7398        The new Except instance.
7399    """
7400    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7401    return _apply_set_operation(
7402        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7403    )
7404
7405
7406def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7407    """
7408    Initializes a syntax tree from one or multiple SELECT expressions.
7409
7410    Example:
7411        >>> select("col1", "col2").from_("tbl").sql()
7412        'SELECT col1, col2 FROM tbl'
7413
7414    Args:
7415        *expressions: the SQL code string to parse as the expressions of a
7416            SELECT statement. If an Expression instance is passed, this is used as-is.
7417        dialect: the dialect used to parse the input expressions (in the case that an
7418            input expression is a SQL string).
7419        **opts: other options to use to parse the input expressions (again, in the case
7420            that an input expression is a SQL string).
7421
7422    Returns:
7423        Select: the syntax tree for the SELECT statement.
7424    """
7425    return Select().select(*expressions, dialect=dialect, **opts)
7426
7427
7428def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7429    """
7430    Initializes a syntax tree from a FROM expression.
7431
7432    Example:
7433        >>> from_("tbl").select("col1", "col2").sql()
7434        'SELECT col1, col2 FROM tbl'
7435
7436    Args:
7437        *expression: the SQL code string to parse as the FROM expressions of a
7438            SELECT statement. If an Expression instance is passed, this is used as-is.
7439        dialect: the dialect used to parse the input expression (in the case that the
7440            input expression is a SQL string).
7441        **opts: other options to use to parse the input expressions (again, in the case
7442            that the input expression is a SQL string).
7443
7444    Returns:
7445        Select: the syntax tree for the SELECT statement.
7446    """
7447    return Select().from_(expression, dialect=dialect, **opts)
7448
7449
7450def update(
7451    table: str | Table,
7452    properties: t.Optional[dict] = None,
7453    where: t.Optional[ExpOrStr] = None,
7454    from_: t.Optional[ExpOrStr] = None,
7455    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7456    dialect: DialectType = None,
7457    **opts,
7458) -> Update:
7459    """
7460    Creates an update statement.
7461
7462    Example:
7463        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
7464        "WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
7465
7466    Args:
7467        properties: dictionary of properties to SET which are
7468            auto converted to sql objects eg None -> NULL
7469        where: sql conditional parsed into a WHERE statement
7470        from_: sql statement parsed into a FROM statement
7471        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7472        dialect: the dialect used to parse the input expressions.
7473        **opts: other options to use to parse the input expressions.
7474
7475    Returns:
7476        Update: the syntax tree for the UPDATE statement.
7477    """
7478    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7479    if properties:
7480        update_expr.set(
7481            "expressions",
7482            [
7483                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7484                for k, v in properties.items()
7485            ],
7486        )
7487    if from_:
7488        update_expr.set(
7489            "from",
7490            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7491        )
7492    if isinstance(where, Condition):
7493        where = Where(this=where)
7494    if where:
7495        update_expr.set(
7496            "where",
7497            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7498        )
7499    if with_:
7500        cte_list = [
7501            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7502            for alias, qry in with_.items()
7503        ]
7504        update_expr.set(
7505            "with",
7506            With(expressions=cte_list),
7507        )
7508    return update_expr
7509
7510
7511def delete(
7512    table: ExpOrStr,
7513    where: t.Optional[ExpOrStr] = None,
7514    returning: t.Optional[ExpOrStr] = None,
7515    dialect: DialectType = None,
7516    **opts,
7517) -> Delete:
7518    """
7519    Builds a delete statement.
7520
7521    Example:
7522        >>> delete("my_table", where="id > 1").sql()
7523        'DELETE FROM my_table WHERE id > 1'
7524
7525    Args:
7526        where: sql conditional parsed into a WHERE statement
7527        returning: sql conditional parsed into a RETURNING statement
7528        dialect: the dialect used to parse the input expressions.
7529        **opts: other options to use to parse the input expressions.
7530
7531    Returns:
7532        Delete: the syntax tree for the DELETE statement.
7533    """
7534    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7535    if where:
7536        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7537    if returning:
7538        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7539    return delete_expr
7540
7541
7542def insert(
7543    expression: ExpOrStr,
7544    into: ExpOrStr,
7545    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7546    overwrite: t.Optional[bool] = None,
7547    returning: t.Optional[ExpOrStr] = None,
7548    dialect: DialectType = None,
7549    copy: bool = True,
7550    **opts,
7551) -> Insert:
7552    """
7553    Builds an INSERT statement.
7554
7555    Example:
7556        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7557        'INSERT INTO tbl VALUES (1, 2, 3)'
7558
7559    Args:
7560        expression: the sql string or expression of the INSERT statement
7561        into: the tbl to insert data to.
7562        columns: optionally the table's column names.
7563        overwrite: whether to INSERT OVERWRITE or not.
7564        returning: sql conditional parsed into a RETURNING statement
7565        dialect: the dialect used to parse the input expressions.
7566        copy: whether to copy the expression.
7567        **opts: other options to use to parse the input expressions.
7568
7569    Returns:
7570        Insert: the syntax tree for the INSERT statement.
7571    """
7572    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7573    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7574
7575    if columns:
7576        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7577
7578    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7579
7580    if returning:
7581        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7582
7583    return insert
7584
7585
7586def merge(
7587    *when_exprs: ExpOrStr,
7588    into: ExpOrStr,
7589    using: ExpOrStr,
7590    on: ExpOrStr,
7591    returning: t.Optional[ExpOrStr] = None,
7592    dialect: DialectType = None,
7593    copy: bool = True,
7594    **opts,
7595) -> Merge:
7596    """
7597    Builds a MERGE statement.
7598
7599    Example:
7600        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7601        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7602        ...       into="my_table",
7603        ...       using="source_table",
7604        ...       on="my_table.id = source_table.id").sql()
7605        'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
7606
7607    Args:
7608        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7609        into: The target table to merge data into.
7610        using: The source table to merge data from.
7611        on: The join condition for the merge.
7612        returning: The columns to return from the merge.
7613        dialect: The dialect used to parse the input expressions.
7614        copy: Whether to copy the expression.
7615        **opts: Other options to use to parse the input expressions.
7616
7617    Returns:
7618        Merge: The syntax tree for the MERGE statement.
7619    """
7620    expressions: t.List[Expression] = []
7621    for when_expr in when_exprs:
7622        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7623        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7624
7625    merge = Merge(
7626        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7627        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7628        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7629        whens=Whens(expressions=expressions),
7630    )
7631    if returning:
7632        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7633
7634    return merge
7635
7636
7637def condition(
7638    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7639) -> Condition:
7640    """
7641    Initialize a logical condition expression.
7642
7643    Example:
7644        >>> condition("x=1").sql()
7645        'x = 1'
7646
7647        This is helpful for composing larger logical syntax trees:
7648        >>> where = condition("x=1")
7649        >>> where = where.and_("y=1")
7650        >>> Select().from_("tbl").select("*").where(where).sql()
7651        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7652
7653    Args:
7654        *expression: the SQL code string to parse.
7655            If an Expression instance is passed, this is used as-is.
7656        dialect: the dialect used to parse the input expression (in the case that the
7657            input expression is a SQL string).
7658        copy: Whether to copy `expression` (only applies to expressions).
7659        **opts: other options to use to parse the input expressions (again, in the case
7660            that the input expression is a SQL string).
7661
7662    Returns:
7663        The new Condition instance
7664    """
7665    return maybe_parse(
7666        expression,
7667        into=Condition,
7668        dialect=dialect,
7669        copy=copy,
7670        **opts,
7671    )
7672
7673
7674def and_(
7675    *expressions: t.Optional[ExpOrStr],
7676    dialect: DialectType = None,
7677    copy: bool = True,
7678    wrap: bool = True,
7679    **opts,
7680) -> Condition:
7681    """
7682    Combine multiple conditions with an AND logical operator.
7683
7684    Example:
7685        >>> and_("x=1", and_("y=1", "z=1")).sql()
7686        'x = 1 AND (y = 1 AND z = 1)'
7687
7688    Args:
7689        *expressions: the SQL code strings to parse.
7690            If an Expression instance is passed, this is used as-is.
7691        dialect: the dialect used to parse the input expression.
7692        copy: whether to copy `expressions` (only applies to Expressions).
7693        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7694            precedence issues, but can be turned off when the produced AST is too deep and
7695            causes recursion-related issues.
7696        **opts: other options to use to parse the input expressions.
7697
7698    Returns:
7699        The new condition
7700    """
7701    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
7702
7703
7704def or_(
7705    *expressions: t.Optional[ExpOrStr],
7706    dialect: DialectType = None,
7707    copy: bool = True,
7708    wrap: bool = True,
7709    **opts,
7710) -> Condition:
7711    """
7712    Combine multiple conditions with an OR logical operator.
7713
7714    Example:
7715        >>> or_("x=1", or_("y=1", "z=1")).sql()
7716        'x = 1 OR (y = 1 OR z = 1)'
7717
7718    Args:
7719        *expressions: the SQL code strings to parse.
7720            If an Expression instance is passed, this is used as-is.
7721        dialect: the dialect used to parse the input expression.
7722        copy: whether to copy `expressions` (only applies to Expressions).
7723        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7724            precedence issues, but can be turned off when the produced AST is too deep and
7725            causes recursion-related issues.
7726        **opts: other options to use to parse the input expressions.
7727
7728    Returns:
7729        The new condition
7730    """
7731    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
7732
7733
7734def xor(
7735    *expressions: t.Optional[ExpOrStr],
7736    dialect: DialectType = None,
7737    copy: bool = True,
7738    wrap: bool = True,
7739    **opts,
7740) -> Condition:
7741    """
7742    Combine multiple conditions with an XOR logical operator.
7743
7744    Example:
7745        >>> xor("x=1", xor("y=1", "z=1")).sql()
7746        'x = 1 XOR (y = 1 XOR z = 1)'
7747
7748    Args:
7749        *expressions: the SQL code strings to parse.
7750            If an Expression instance is passed, this is used as-is.
7751        dialect: the dialect used to parse the input expression.
7752        copy: whether to copy `expressions` (only applies to Expressions).
7753        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7754            precedence issues, but can be turned off when the produced AST is too deep and
7755            causes recursion-related issues.
7756        **opts: other options to use to parse the input expressions.
7757
7758    Returns:
7759        The new condition
7760    """
7761    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
7762
7763
7764def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7765    """
7766    Wrap a condition with a NOT operator.
7767
7768    Example:
7769        >>> not_("this_suit='black'").sql()
7770        "NOT this_suit = 'black'"
7771
7772    Args:
7773        expression: the SQL code string to parse.
7774            If an Expression instance is passed, this is used as-is.
7775        dialect: the dialect used to parse the input expression.
7776        copy: whether to copy the expression or not.
7777        **opts: other options to use to parse the input expressions.
7778
7779    Returns:
7780        The new condition.
7781    """
7782    this = condition(
7783        expression,
7784        dialect=dialect,
7785        copy=copy,
7786        **opts,
7787    )
7788    return Not(this=_wrap(this, Connector))
7789
7790
7791def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7792    """
7793    Wrap an expression in parentheses.
7794
7795    Example:
7796        >>> paren("5 + 3").sql()
7797        '(5 + 3)'
7798
7799    Args:
7800        expression: the SQL code string to parse.
7801            If an Expression instance is passed, this is used as-is.
7802        copy: whether to copy the expression or not.
7803
7804    Returns:
7805        The wrapped expression.
7806    """
7807    return Paren(this=maybe_parse(expression, copy=copy))
7808
7809
7810SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
7811
7812
7813@t.overload
7814def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
7815
7816
7817@t.overload
7818def to_identifier(
7819    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
7820) -> Identifier: ...
7821
7822
7823def to_identifier(name, quoted=None, copy=True):
7824    """Builds an identifier.
7825
7826    Args:
7827        name: The name to turn into an identifier.
7828        quoted: Whether to force quote the identifier.
7829        copy: Whether to copy name if it's an Identifier.
7830
7831    Returns:
7832        The identifier ast node.
7833    """
7834
7835    if name is None:
7836        return None
7837
7838    if isinstance(name, Identifier):
7839        identifier = maybe_copy(name, copy)
7840    elif isinstance(name, str):
7841        identifier = Identifier(
7842            this=name,
7843            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7844        )
7845    else:
7846        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7847    return identifier
7848
7849
7850def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7851    """
7852    Parses a given string into an identifier.
7853
7854    Args:
7855        name: The name to parse into an identifier.
7856        dialect: The dialect to parse against.
7857
7858    Returns:
7859        The identifier ast node.
7860    """
7861    try:
7862        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7863    except (ParseError, TokenError):
7864        expression = to_identifier(name)
7865
7866    return expression
7867
7868
7869INTERVAL_STRING_RE = re.compile(r"\s*(-?[0-9]+)\s*([a-zA-Z]+)\s*")
7870
7871
7872def to_interval(interval: str | Literal) -> Interval:
7873    """Builds an interval expression from a string like '1 day' or '5 months'."""
7874    if isinstance(interval, Literal):
7875        if not interval.is_string:
7876            raise ValueError("Invalid interval string.")
7877
7878        interval = interval.this
7879
7880    interval = maybe_parse(f"INTERVAL {interval}")
7881    assert isinstance(interval, Interval)
7882    return interval
7883
7884
7885def to_table(
7886    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7887) -> Table:
7888    """
7889    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7890    If a table is passed in then that table is returned.
7891
7892    Args:
7893        sql_path: a `[catalog].[schema].[table]` string.
7894        dialect: the source dialect according to which the table name will be parsed.
7895        copy: Whether to copy a table if it is passed in.
7896        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7897
7898    Returns:
7899        A table expression.
7900    """
7901    if isinstance(sql_path, Table):
7902        return maybe_copy(sql_path, copy=copy)
7903
7904    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7905
7906    for k, v in kwargs.items():
7907        table.set(k, v)
7908
7909    return table
7910
7911
7912def to_column(
7913    sql_path: str | Column,
7914    quoted: t.Optional[bool] = None,
7915    dialect: DialectType = None,
7916    copy: bool = True,
7917    **kwargs,
7918) -> Column:
7919    """
7920    Create a column from a `[table].[column]` sql path. Table is optional.
7921    If a column is passed in then that column is returned.
7922
7923    Args:
7924        sql_path: a `[table].[column]` string.
7925        quoted: Whether or not to force quote identifiers.
7926        dialect: the source dialect according to which the column name will be parsed.
7927        copy: Whether to copy a column if it is passed in.
7928        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7929
7930    Returns:
7931        A column expression.
7932    """
7933    if isinstance(sql_path, Column):
7934        return maybe_copy(sql_path, copy=copy)
7935
7936    try:
7937        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7938    except ParseError:
7939        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7940
7941    for k, v in kwargs.items():
7942        col.set(k, v)
7943
7944    if quoted:
7945        for i in col.find_all(Identifier):
7946            i.set("quoted", True)
7947
7948    return col
7949
7950
7951def alias_(
7952    expression: ExpOrStr,
7953    alias: t.Optional[str | Identifier],
7954    table: bool | t.Sequence[str | Identifier] = False,
7955    quoted: t.Optional[bool] = None,
7956    dialect: DialectType = None,
7957    copy: bool = True,
7958    **opts,
7959):
7960    """Create an Alias expression.
7961
7962    Example:
7963        >>> alias_('foo', 'bar').sql()
7964        'foo AS bar'
7965
7966        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7967        '(SELECT 1, 2) AS bar(a, b)'
7968
7969    Args:
7970        expression: the SQL code strings to parse.
7971            If an Expression instance is passed, this is used as-is.
7972        alias: the alias name to use. If the name has
7973            special characters it is quoted.
7974        table: Whether to create a table alias, can also be a list of columns.
7975        quoted: whether to quote the alias
7976        dialect: the dialect used to parse the input expression.
7977        copy: Whether to copy the expression.
7978        **opts: other options to use to parse the input expressions.
7979
7980    Returns:
7981        Alias: the aliased expression
7982    """
7983    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7984    alias = to_identifier(alias, quoted=quoted)
7985
7986    if table:
7987        table_alias = TableAlias(this=alias)
7988        exp.set("alias", table_alias)
7989
7990        if not isinstance(table, bool):
7991            for column in table:
7992                table_alias.append("columns", to_identifier(column, quoted=quoted))
7993
7994        return exp
7995
7996    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7997    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7998    # for the complete Window expression.
7999    #
8000    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8001
8002    if "alias" in exp.arg_types and not isinstance(exp, Window):
8003        exp.set("alias", alias)
8004        return exp
8005    return Alias(this=exp, alias=alias)
8006
8007
8008def subquery(
8009    expression: ExpOrStr,
8010    alias: t.Optional[Identifier | str] = None,
8011    dialect: DialectType = None,
8012    **opts,
8013) -> Select:
8014    """
8015    Build a subquery expression that's selected from.
8016
8017    Example:
8018        >>> subquery('select x from tbl', 'bar').select('x').sql()
8019        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8020
8021    Args:
8022        expression: the SQL code strings to parse.
8023            If an Expression instance is passed, this is used as-is.
8024        alias: the alias name to use.
8025        dialect: the dialect used to parse the input expression.
8026        **opts: other options to use to parse the input expressions.
8027
8028    Returns:
8029        A new Select instance with the subquery expression included.
8030    """
8031
8032    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8033    return Select().from_(expression, dialect=dialect, **opts)
8034
8035
8036@t.overload
8037def column(
8038    col: str | Identifier,
8039    table: t.Optional[str | Identifier] = None,
8040    db: t.Optional[str | Identifier] = None,
8041    catalog: t.Optional[str | Identifier] = None,
8042    *,
8043    fields: t.Collection[t.Union[str, Identifier]],
8044    quoted: t.Optional[bool] = None,
8045    copy: bool = True,
8046) -> Dot:
8047    pass
8048
8049
8050@t.overload
8051def column(
8052    col: str | Identifier,
8053    table: t.Optional[str | Identifier] = None,
8054    db: t.Optional[str | Identifier] = None,
8055    catalog: t.Optional[str | Identifier] = None,
8056    *,
8057    fields: Lit[None] = None,
8058    quoted: t.Optional[bool] = None,
8059    copy: bool = True,
8060) -> Column:
8061    pass
8062
8063
8064def column(
8065    col,
8066    table=None,
8067    db=None,
8068    catalog=None,
8069    *,
8070    fields=None,
8071    quoted=None,
8072    copy=True,
8073):
8074    """
8075    Build a Column.
8076
8077    Args:
8078        col: Column name.
8079        table: Table name.
8080        db: Database name.
8081        catalog: Catalog name.
8082        fields: Additional fields using dots.
8083        quoted: Whether to force quotes on the column's identifiers.
8084        copy: Whether to copy identifiers if passed in.
8085
8086    Returns:
8087        The new Column instance.
8088    """
8089    this = Column(
8090        this=to_identifier(col, quoted=quoted, copy=copy),
8091        table=to_identifier(table, quoted=quoted, copy=copy),
8092        db=to_identifier(db, quoted=quoted, copy=copy),
8093        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8094    )
8095
8096    if fields:
8097        this = Dot.build(
8098            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8099        )
8100    return this
8101
8102
8103def cast(
8104    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8105) -> Cast:
8106    """Cast an expression to a data type.
8107
8108    Example:
8109        >>> cast('x + 1', 'int').sql()
8110        'CAST(x + 1 AS INT)'
8111
8112    Args:
8113        expression: The expression to cast.
8114        to: The datatype to cast to.
8115        copy: Whether to copy the supplied expressions.
8116        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8117            - The expression to be cast is already a exp.Cast expression
8118            - The existing cast is to a type that is logically equivalent to new type
8119
8120            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8121            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8122            and instead just return the original expression `CAST(x as DATETIME)`.
8123
8124            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8125            mapping is applied in the target dialect generator.
8126
8127    Returns:
8128        The new Cast instance.
8129    """
8130    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8131    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8132
8133    # dont re-cast if the expression is already a cast to the correct type
8134    if isinstance(expr, Cast):
8135        from sqlglot.dialects.dialect import Dialect
8136
8137        target_dialect = Dialect.get_or_raise(dialect)
8138        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8139
8140        existing_cast_type: DataType.Type = expr.to.this
8141        new_cast_type: DataType.Type = data_type.this
8142        types_are_equivalent = type_mapping.get(
8143            existing_cast_type, existing_cast_type.value
8144        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8145
8146        if expr.is_type(data_type) or types_are_equivalent:
8147            return expr
8148
8149    expr = Cast(this=expr, to=data_type)
8150    expr.type = data_type
8151
8152    return expr
8153
8154
8155def table_(
8156    table: Identifier | str,
8157    db: t.Optional[Identifier | str] = None,
8158    catalog: t.Optional[Identifier | str] = None,
8159    quoted: t.Optional[bool] = None,
8160    alias: t.Optional[Identifier | str] = None,
8161) -> Table:
8162    """Build a Table.
8163
8164    Args:
8165        table: Table name.
8166        db: Database name.
8167        catalog: Catalog name.
8168        quote: Whether to force quotes on the table's identifiers.
8169        alias: Table's alias.
8170
8171    Returns:
8172        The new Table instance.
8173    """
8174    return Table(
8175        this=to_identifier(table, quoted=quoted) if table else None,
8176        db=to_identifier(db, quoted=quoted) if db else None,
8177        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8178        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8179    )
8180
8181
8182def values(
8183    values: t.Iterable[t.Tuple[t.Any, ...]],
8184    alias: t.Optional[str] = None,
8185    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8186) -> Values:
8187    """Build VALUES statement.
8188
8189    Example:
8190        >>> values([(1, '2')]).sql()
8191        "VALUES (1, '2')"
8192
8193    Args:
8194        values: values statements that will be converted to SQL
8195        alias: optional alias
8196        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8197         If either are provided then an alias is also required.
8198
8199    Returns:
8200        Values: the Values expression object
8201    """
8202    if columns and not alias:
8203        raise ValueError("Alias is required when providing columns")
8204
8205    return Values(
8206        expressions=[convert(tup) for tup in values],
8207        alias=(
8208            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8209            if columns
8210            else (TableAlias(this=to_identifier(alias)) if alias else None)
8211        ),
8212    )
8213
8214
8215def var(name: t.Optional[ExpOrStr]) -> Var:
8216    """Build a SQL variable.
8217
8218    Example:
8219        >>> repr(var('x'))
8220        'Var(this=x)'
8221
8222        >>> repr(var(column('x', table='y')))
8223        'Var(this=x)'
8224
8225    Args:
8226        name: The name of the var or an expression who's name will become the var.
8227
8228    Returns:
8229        The new variable node.
8230    """
8231    if not name:
8232        raise ValueError("Cannot convert empty name into var.")
8233
8234    if isinstance(name, Expression):
8235        name = name.name
8236    return Var(this=name)
8237
8238
8239def rename_table(
8240    old_name: str | Table,
8241    new_name: str | Table,
8242    dialect: DialectType = None,
8243) -> Alter:
8244    """Build ALTER TABLE... RENAME... expression
8245
8246    Args:
8247        old_name: The old name of the table
8248        new_name: The new name of the table
8249        dialect: The dialect to parse the table.
8250
8251    Returns:
8252        Alter table expression
8253    """
8254    old_table = to_table(old_name, dialect=dialect)
8255    new_table = to_table(new_name, dialect=dialect)
8256    return Alter(
8257        this=old_table,
8258        kind="TABLE",
8259        actions=[
8260            AlterRename(this=new_table),
8261        ],
8262    )
8263
8264
8265def rename_column(
8266    table_name: str | Table,
8267    old_column_name: str | Column,
8268    new_column_name: str | Column,
8269    exists: t.Optional[bool] = None,
8270    dialect: DialectType = None,
8271) -> Alter:
8272    """Build ALTER TABLE... RENAME COLUMN... expression
8273
8274    Args:
8275        table_name: Name of the table
8276        old_column: The old name of the column
8277        new_column: The new name of the column
8278        exists: Whether to add the `IF EXISTS` clause
8279        dialect: The dialect to parse the table/column.
8280
8281    Returns:
8282        Alter table expression
8283    """
8284    table = to_table(table_name, dialect=dialect)
8285    old_column = to_column(old_column_name, dialect=dialect)
8286    new_column = to_column(new_column_name, dialect=dialect)
8287    return Alter(
8288        this=table,
8289        kind="TABLE",
8290        actions=[
8291            RenameColumn(this=old_column, to=new_column, exists=exists),
8292        ],
8293    )
8294
8295
8296def convert(value: t.Any, copy: bool = False) -> Expression:
8297    """Convert a python value into an expression object.
8298
8299    Raises an error if a conversion is not possible.
8300
8301    Args:
8302        value: A python object.
8303        copy: Whether to copy `value` (only applies to Expressions and collections).
8304
8305    Returns:
8306        The equivalent expression object.
8307    """
8308    if isinstance(value, Expression):
8309        return maybe_copy(value, copy)
8310    if isinstance(value, str):
8311        return Literal.string(value)
8312    if isinstance(value, bool):
8313        return Boolean(this=value)
8314    if value is None or (isinstance(value, float) and math.isnan(value)):
8315        return null()
8316    if isinstance(value, numbers.Number):
8317        return Literal.number(value)
8318    if isinstance(value, bytes):
8319        return HexString(this=value.hex())
8320    if isinstance(value, datetime.datetime):
8321        datetime_literal = Literal.string(value.isoformat(sep=" "))
8322
8323        tz = None
8324        if value.tzinfo:
8325            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8326            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8327            tz = Literal.string(str(value.tzinfo))
8328
8329        return TimeStrToTime(this=datetime_literal, zone=tz)
8330    if isinstance(value, datetime.date):
8331        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8332        return DateStrToDate(this=date_literal)
8333    if isinstance(value, tuple):
8334        if hasattr(value, "_fields"):
8335            return Struct(
8336                expressions=[
8337                    PropertyEQ(
8338                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8339                    )
8340                    for k in value._fields
8341                ]
8342            )
8343        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8344    if isinstance(value, list):
8345        return Array(expressions=[convert(v, copy=copy) for v in value])
8346    if isinstance(value, dict):
8347        return Map(
8348            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8349            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8350        )
8351    if hasattr(value, "__dict__"):
8352        return Struct(
8353            expressions=[
8354                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8355                for k, v in value.__dict__.items()
8356            ]
8357        )
8358    raise ValueError(f"Cannot convert {value}")
8359
8360
8361def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8362    """
8363    Replace children of an expression with the result of a lambda fun(child) -> exp.
8364    """
8365    for k, v in tuple(expression.args.items()):
8366        is_list_arg = type(v) is list
8367
8368        child_nodes = v if is_list_arg else [v]
8369        new_child_nodes = []
8370
8371        for cn in child_nodes:
8372            if isinstance(cn, Expression):
8373                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8374                    new_child_nodes.append(child_node)
8375            else:
8376                new_child_nodes.append(cn)
8377
8378        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
8379
8380
8381def replace_tree(
8382    expression: Expression,
8383    fun: t.Callable,
8384    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8385) -> Expression:
8386    """
8387    Replace an entire tree with the result of function calls on each node.
8388
8389    This will be traversed in reverse dfs, so leaves first.
8390    If new nodes are created as a result of function calls, they will also be traversed.
8391    """
8392    stack = list(expression.dfs(prune=prune))
8393
8394    while stack:
8395        node = stack.pop()
8396        new_node = fun(node)
8397
8398        if new_node is not node:
8399            node.replace(new_node)
8400
8401            if isinstance(new_node, Expression):
8402                stack.append(new_node)
8403
8404    return new_node
8405
8406
8407def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8408    """
8409    Return all table names referenced through columns in an expression.
8410
8411    Example:
8412        >>> import sqlglot
8413        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8414        ['a', 'c']
8415
8416    Args:
8417        expression: expression to find table names.
8418        exclude: a table name to exclude
8419
8420    Returns:
8421        A list of unique names.
8422    """
8423    return {
8424        table
8425        for table in (column.table for column in expression.find_all(Column))
8426        if table and table != exclude
8427    }
8428
8429
8430def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8431    """Get the full name of a table as a string.
8432
8433    Args:
8434        table: Table expression node or string.
8435        dialect: The dialect to generate the table name for.
8436        identify: Determines when an identifier should be quoted. Possible values are:
8437            False (default): Never quote, except in cases where it's mandatory by the dialect.
8438            True: Always quote.
8439
8440    Examples:
8441        >>> from sqlglot import exp, parse_one
8442        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8443        'a.b.c'
8444
8445    Returns:
8446        The table name.
8447    """
8448
8449    table = maybe_parse(table, into=Table, dialect=dialect)
8450
8451    if not table:
8452        raise ValueError(f"Cannot parse {table}")
8453
8454    return ".".join(
8455        (
8456            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8457            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8458            else part.name
8459        )
8460        for part in table.parts
8461    )
8462
8463
8464def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8465    """Returns a case normalized table name without quotes.
8466
8467    Args:
8468        table: the table to normalize
8469        dialect: the dialect to use for normalization rules
8470        copy: whether to copy the expression.
8471
8472    Examples:
8473        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8474        'A-B.c'
8475    """
8476    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8477
8478    return ".".join(
8479        p.name
8480        for p in normalize_identifiers(
8481            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8482        ).parts
8483    )
8484
8485
8486def replace_tables(
8487    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8488) -> E:
8489    """Replace all tables in expression according to the mapping.
8490
8491    Args:
8492        expression: expression node to be transformed and replaced.
8493        mapping: mapping of table names.
8494        dialect: the dialect of the mapping table
8495        copy: whether to copy the expression.
8496
8497    Examples:
8498        >>> from sqlglot import exp, parse_one
8499        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8500        'SELECT * FROM c /* a.b */'
8501
8502    Returns:
8503        The mapped expression.
8504    """
8505
8506    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8507
8508    def _replace_tables(node: Expression) -> Expression:
8509        if isinstance(node, Table) and node.meta.get("replace") is not False:
8510            original = normalize_table_name(node, dialect=dialect)
8511            new_name = mapping.get(original)
8512
8513            if new_name:
8514                table = to_table(
8515                    new_name,
8516                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8517                    dialect=dialect,
8518                )
8519                table.add_comments([original])
8520                return table
8521        return node
8522
8523    return expression.transform(_replace_tables, copy=copy)  # type: ignore
8524
8525
8526def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8527    """Replace placeholders in an expression.
8528
8529    Args:
8530        expression: expression node to be transformed and replaced.
8531        args: positional names that will substitute unnamed placeholders in the given order.
8532        kwargs: keyword arguments that will substitute named placeholders.
8533
8534    Examples:
8535        >>> from sqlglot import exp, parse_one
8536        >>> replace_placeholders(
8537        ...     parse_one("select * from :tbl where ? = ?"),
8538        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8539        ... ).sql()
8540        "SELECT * FROM foo WHERE str_col = 'b'"
8541
8542    Returns:
8543        The mapped expression.
8544    """
8545
8546    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8547        if isinstance(node, Placeholder):
8548            if node.this:
8549                new_name = kwargs.get(node.this)
8550                if new_name is not None:
8551                    return convert(new_name)
8552            else:
8553                try:
8554                    return convert(next(args))
8555                except StopIteration:
8556                    pass
8557        return node
8558
8559    return expression.transform(_replace_placeholders, iter(args), **kwargs)
8560
8561
8562def expand(
8563    expression: Expression,
8564    sources: t.Dict[str, Query | t.Callable[[], Query]],
8565    dialect: DialectType = None,
8566    copy: bool = True,
8567) -> Expression:
8568    """Transforms an expression by expanding all referenced sources into subqueries.
8569
8570    Examples:
8571        >>> from sqlglot import parse_one
8572        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8573        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8574
8575        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8576        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8577
8578    Args:
8579        expression: The expression to expand.
8580        sources: A dict of name to query or a callable that provides a query on demand.
8581        dialect: The dialect of the sources dict or the callable.
8582        copy: Whether to copy the expression during transformation. Defaults to True.
8583
8584    Returns:
8585        The transformed expression.
8586    """
8587    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8588
8589    def _expand(node: Expression):
8590        if isinstance(node, Table):
8591            name = normalize_table_name(node, dialect=dialect)
8592            source = normalized_sources.get(name)
8593
8594            if source:
8595                # Create a subquery with the same alias (or table name if no alias)
8596                parsed_source = source() if callable(source) else source
8597                subquery = parsed_source.subquery(node.alias or name)
8598                subquery.comments = [f"source: {name}"]
8599
8600                # Continue expanding within the subquery
8601                return subquery.transform(_expand, copy=False)
8602
8603        return node
8604
8605    return expression.transform(_expand, copy=copy)
8606
8607
8608def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8609    """
8610    Returns a Func expression.
8611
8612    Examples:
8613        >>> func("abs", 5).sql()
8614        'ABS(5)'
8615
8616        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8617        'CAST(5 AS DOUBLE)'
8618
8619    Args:
8620        name: the name of the function to build.
8621        args: the args used to instantiate the function of interest.
8622        copy: whether to copy the argument expressions.
8623        dialect: the source dialect.
8624        kwargs: the kwargs used to instantiate the function of interest.
8625
8626    Note:
8627        The arguments `args` and `kwargs` are mutually exclusive.
8628
8629    Returns:
8630        An instance of the function of interest, or an anonymous function, if `name` doesn't
8631        correspond to an existing `sqlglot.expressions.Func` class.
8632    """
8633    if args and kwargs:
8634        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8635
8636    from sqlglot.dialects.dialect import Dialect
8637
8638    dialect = Dialect.get_or_raise(dialect)
8639
8640    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8641    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8642
8643    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8644    if constructor:
8645        if converted:
8646            if "dialect" in constructor.__code__.co_varnames:
8647                function = constructor(converted, dialect=dialect)
8648            else:
8649                function = constructor(converted)
8650        elif constructor.__name__ == "from_arg_list":
8651            function = constructor.__self__(**kwargs)  # type: ignore
8652        else:
8653            constructor = FUNCTION_BY_NAME.get(name.upper())
8654            if constructor:
8655                function = constructor(**kwargs)
8656            else:
8657                raise ValueError(
8658                    f"Unable to convert '{name}' into a Func. Either manually construct "
8659                    "the Func expression of interest or parse the function call."
8660                )
8661    else:
8662        kwargs = kwargs or {"expressions": converted}
8663        function = Anonymous(this=name, **kwargs)
8664
8665    for error_message in function.error_messages(converted):
8666        raise ValueError(error_message)
8667
8668    return function
8669
8670
8671def case(
8672    expression: t.Optional[ExpOrStr] = None,
8673    **opts,
8674) -> Case:
8675    """
8676    Initialize a CASE statement.
8677
8678    Example:
8679        case().when("a = 1", "foo").else_("bar")
8680
8681    Args:
8682        expression: Optionally, the input expression (not all dialects support this)
8683        **opts: Extra keyword arguments for parsing `expression`
8684    """
8685    if expression is not None:
8686        this = maybe_parse(expression, **opts)
8687    else:
8688        this = None
8689    return Case(this=this, ifs=[])
8690
8691
8692def array(
8693    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8694) -> Array:
8695    """
8696    Returns an array.
8697
8698    Examples:
8699        >>> array(1, 'x').sql()
8700        'ARRAY(1, x)'
8701
8702    Args:
8703        expressions: the expressions to add to the array.
8704        copy: whether to copy the argument expressions.
8705        dialect: the source dialect.
8706        kwargs: the kwargs used to instantiate the function of interest.
8707
8708    Returns:
8709        An array expression.
8710    """
8711    return Array(
8712        expressions=[
8713            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8714            for expression in expressions
8715        ]
8716    )
8717
8718
8719def tuple_(
8720    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8721) -> Tuple:
8722    """
8723    Returns an tuple.
8724
8725    Examples:
8726        >>> tuple_(1, 'x').sql()
8727        '(1, x)'
8728
8729    Args:
8730        expressions: the expressions to add to the tuple.
8731        copy: whether to copy the argument expressions.
8732        dialect: the source dialect.
8733        kwargs: the kwargs used to instantiate the function of interest.
8734
8735    Returns:
8736        A tuple expression.
8737    """
8738    return Tuple(
8739        expressions=[
8740            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8741            for expression in expressions
8742        ]
8743    )
8744
8745
8746def true() -> Boolean:
8747    """
8748    Returns a true Boolean expression.
8749    """
8750    return Boolean(this=True)
8751
8752
8753def false() -> Boolean:
8754    """
8755    Returns a false Boolean expression.
8756    """
8757    return Boolean(this=False)
8758
8759
8760def null() -> Null:
8761    """
8762    Returns a Null expression.
8763    """
8764    return Null()
8765
8766
8767NONNULL_CONSTANTS = (
8768    Literal,
8769    Boolean,
8770)
8771
8772CONSTANTS = (
8773    Literal,
8774    Boolean,
8775    Null,
8776)
SQLGLOT_META = 'sqlglot.meta'
SQLGLOT_ANONYMOUS = 'sqlglot.anonymous'
TABLE_PARTS = ('this', 'db', 'catalog')
COLUMN_PARTS = ('this', 'table', 'db', 'catalog')
class Expression:
  70class Expression(metaclass=_Expression):
  71    """
  72    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  73    context, such as its child expressions, their names (arg keys), and whether a given child expression
  74    is optional or not.
  75
  76    Attributes:
  77        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  78            and representing expressions as strings.
  79        arg_types: determines the arguments (child nodes) supported by an expression. It maps
  80            arg keys to booleans that indicate whether the corresponding args are optional.
  81        parent: a reference to the parent expression (or None, in case of root expressions).
  82        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  83            uses to refer to it.
  84        index: the index of an expression if it is inside of a list argument in its parent.
  85        comments: a list of comments that are associated with a given expression. This is used in
  86            order to preserve comments when transpiling SQL code.
  87        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  88            optimizer, in order to enable some transformations that require type information.
  89        meta: a dictionary that can be used to store useful metadata for a given expression.
  90
  91    Example:
  92        >>> class Foo(Expression):
  93        ...     arg_types = {"this": True, "expression": False}
  94
  95        The above definition informs us that Foo is an Expression that requires an argument called
  96        "this" and may also optionally receive an argument called "expression".
  97
  98    Args:
  99        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
 100    """
 101
 102    key = "expression"
 103    arg_types = {"this": True}
 104    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
 105
 106    def __init__(self, **args: t.Any):
 107        self.args: t.Dict[str, t.Any] = args
 108        self.parent: t.Optional[Expression] = None
 109        self.arg_key: t.Optional[str] = None
 110        self.index: t.Optional[int] = None
 111        self.comments: t.Optional[t.List[str]] = None
 112        self._type: t.Optional[DataType] = None
 113        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 114        self._hash: t.Optional[int] = None
 115
 116        for arg_key, value in self.args.items():
 117            self._set_parent(arg_key, value)
 118
 119    def __eq__(self, other) -> bool:
 120        return type(self) is type(other) and hash(self) == hash(other)
 121
 122    @property
 123    def hashable_args(self) -> t.Any:
 124        return frozenset(
 125            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 126            for k, v in self.args.items()
 127            if not (v is None or v is False or (type(v) is list and not v))
 128        )
 129
 130    def __hash__(self) -> int:
 131        if self._hash is not None:
 132            return self._hash
 133
 134        return hash((self.__class__, self.hashable_args))
 135
 136    @property
 137    def this(self) -> t.Any:
 138        """
 139        Retrieves the argument with key "this".
 140        """
 141        return self.args.get("this")
 142
 143    @property
 144    def expression(self) -> t.Any:
 145        """
 146        Retrieves the argument with key "expression".
 147        """
 148        return self.args.get("expression")
 149
 150    @property
 151    def expressions(self) -> t.List[t.Any]:
 152        """
 153        Retrieves the argument with key "expressions".
 154        """
 155        return self.args.get("expressions") or []
 156
 157    def text(self, key) -> str:
 158        """
 159        Returns a textual representation of the argument corresponding to "key". This can only be used
 160        for args that are strings or leaf Expression instances, such as identifiers and literals.
 161        """
 162        field = self.args.get(key)
 163        if isinstance(field, str):
 164            return field
 165        if isinstance(field, (Identifier, Literal, Var)):
 166            return field.this
 167        if isinstance(field, (Star, Null)):
 168            return field.name
 169        return ""
 170
 171    @property
 172    def is_string(self) -> bool:
 173        """
 174        Checks whether a Literal expression is a string.
 175        """
 176        return isinstance(self, Literal) and self.args["is_string"]
 177
 178    @property
 179    def is_number(self) -> bool:
 180        """
 181        Checks whether a Literal expression is a number.
 182        """
 183        return (isinstance(self, Literal) and not self.args["is_string"]) or (
 184            isinstance(self, Neg) and self.this.is_number
 185        )
 186
 187    def to_py(self) -> t.Any:
 188        """
 189        Returns a Python object equivalent of the SQL node.
 190        """
 191        raise ValueError(f"{self} cannot be converted to a Python object.")
 192
 193    @property
 194    def is_int(self) -> bool:
 195        """
 196        Checks whether an expression is an integer.
 197        """
 198        return self.is_number and isinstance(self.to_py(), int)
 199
 200    @property
 201    def is_star(self) -> bool:
 202        """Checks whether an expression is a star."""
 203        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 204
 205    @property
 206    def alias(self) -> str:
 207        """
 208        Returns the alias of the expression, or an empty string if it's not aliased.
 209        """
 210        if isinstance(self.args.get("alias"), TableAlias):
 211            return self.args["alias"].name
 212        return self.text("alias")
 213
 214    @property
 215    def alias_column_names(self) -> t.List[str]:
 216        table_alias = self.args.get("alias")
 217        if not table_alias:
 218            return []
 219        return [c.name for c in table_alias.args.get("columns") or []]
 220
 221    @property
 222    def name(self) -> str:
 223        return self.text("this")
 224
 225    @property
 226    def alias_or_name(self) -> str:
 227        return self.alias or self.name
 228
 229    @property
 230    def output_name(self) -> str:
 231        """
 232        Name of the output column if this expression is a selection.
 233
 234        If the Expression has no output name, an empty string is returned.
 235
 236        Example:
 237            >>> from sqlglot import parse_one
 238            >>> parse_one("SELECT a").expressions[0].output_name
 239            'a'
 240            >>> parse_one("SELECT b AS c").expressions[0].output_name
 241            'c'
 242            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 243            ''
 244        """
 245        return ""
 246
 247    @property
 248    def type(self) -> t.Optional[DataType]:
 249        return self._type
 250
 251    @type.setter
 252    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 253        if dtype and not isinstance(dtype, DataType):
 254            dtype = DataType.build(dtype)
 255        self._type = dtype  # type: ignore
 256
 257    def is_type(self, *dtypes) -> bool:
 258        return self.type is not None and self.type.is_type(*dtypes)
 259
 260    def is_leaf(self) -> bool:
 261        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 262
 263    @property
 264    def meta(self) -> t.Dict[str, t.Any]:
 265        if self._meta is None:
 266            self._meta = {}
 267        return self._meta
 268
 269    def __deepcopy__(self, memo):
 270        root = self.__class__()
 271        stack = [(self, root)]
 272
 273        while stack:
 274            node, copy = stack.pop()
 275
 276            if node.comments is not None:
 277                copy.comments = deepcopy(node.comments)
 278            if node._type is not None:
 279                copy._type = deepcopy(node._type)
 280            if node._meta is not None:
 281                copy._meta = deepcopy(node._meta)
 282            if node._hash is not None:
 283                copy._hash = node._hash
 284
 285            for k, vs in node.args.items():
 286                if hasattr(vs, "parent"):
 287                    stack.append((vs, vs.__class__()))
 288                    copy.set(k, stack[-1][-1])
 289                elif type(vs) is list:
 290                    copy.args[k] = []
 291
 292                    for v in vs:
 293                        if hasattr(v, "parent"):
 294                            stack.append((v, v.__class__()))
 295                            copy.append(k, stack[-1][-1])
 296                        else:
 297                            copy.append(k, v)
 298                else:
 299                    copy.args[k] = vs
 300
 301        return root
 302
 303    def copy(self) -> Self:
 304        """
 305        Returns a deep copy of the expression.
 306        """
 307        return deepcopy(self)
 308
 309    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
 310        if self.comments is None:
 311            self.comments = []
 312
 313        if comments:
 314            for comment in comments:
 315                _, *meta = comment.split(SQLGLOT_META)
 316                if meta:
 317                    for kv in "".join(meta).split(","):
 318                        k, *v = kv.split("=")
 319                        value = v[0].strip() if v else True
 320                        self.meta[k.strip()] = to_bool(value)
 321
 322                if not prepend:
 323                    self.comments.append(comment)
 324
 325            if prepend:
 326                self.comments = comments + self.comments
 327
 328    def pop_comments(self) -> t.List[str]:
 329        comments = self.comments or []
 330        self.comments = None
 331        return comments
 332
 333    def append(self, arg_key: str, value: t.Any) -> None:
 334        """
 335        Appends value to arg_key if it's a list or sets it as a new list.
 336
 337        Args:
 338            arg_key (str): name of the list expression arg
 339            value (Any): value to append to the list
 340        """
 341        if type(self.args.get(arg_key)) is not list:
 342            self.args[arg_key] = []
 343        self._set_parent(arg_key, value)
 344        values = self.args[arg_key]
 345        if hasattr(value, "parent"):
 346            value.index = len(values)
 347        values.append(value)
 348
 349    def set(
 350        self,
 351        arg_key: str,
 352        value: t.Any,
 353        index: t.Optional[int] = None,
 354        overwrite: bool = True,
 355    ) -> None:
 356        """
 357        Sets arg_key to value.
 358
 359        Args:
 360            arg_key: name of the expression arg.
 361            value: value to set the arg to.
 362            index: if the arg is a list, this specifies what position to add the value in it.
 363            overwrite: assuming an index is given, this determines whether to overwrite the
 364                list entry instead of only inserting a new value (i.e., like list.insert).
 365        """
 366        if index is not None:
 367            expressions = self.args.get(arg_key) or []
 368
 369            if seq_get(expressions, index) is None:
 370                return
 371            if value is None:
 372                expressions.pop(index)
 373                for v in expressions[index:]:
 374                    v.index = v.index - 1
 375                return
 376
 377            if isinstance(value, list):
 378                expressions.pop(index)
 379                expressions[index:index] = value
 380            elif overwrite:
 381                expressions[index] = value
 382            else:
 383                expressions.insert(index, value)
 384
 385            value = expressions
 386        elif value is None:
 387            self.args.pop(arg_key, None)
 388            return
 389
 390        self.args[arg_key] = value
 391        self._set_parent(arg_key, value, index)
 392
 393    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 394        if hasattr(value, "parent"):
 395            value.parent = self
 396            value.arg_key = arg_key
 397            value.index = index
 398        elif type(value) is list:
 399            for index, v in enumerate(value):
 400                if hasattr(v, "parent"):
 401                    v.parent = self
 402                    v.arg_key = arg_key
 403                    v.index = index
 404
 405    @property
 406    def depth(self) -> int:
 407        """
 408        Returns the depth of this tree.
 409        """
 410        if self.parent:
 411            return self.parent.depth + 1
 412        return 0
 413
 414    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
 415        """Yields the key and expression for all arguments, exploding list args."""
 416        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
 417            if type(vs) is list:
 418                for v in reversed(vs) if reverse else vs:  # type: ignore
 419                    if hasattr(v, "parent"):
 420                        yield v
 421            else:
 422                if hasattr(vs, "parent"):
 423                    yield vs
 424
 425    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 426        """
 427        Returns the first node in this tree which matches at least one of
 428        the specified types.
 429
 430        Args:
 431            expression_types: the expression type(s) to match.
 432            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 433
 434        Returns:
 435            The node which matches the criteria or None if no such node was found.
 436        """
 437        return next(self.find_all(*expression_types, bfs=bfs), None)
 438
 439    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 440        """
 441        Returns a generator object which visits all nodes in this tree and only
 442        yields those that match at least one of the specified expression types.
 443
 444        Args:
 445            expression_types: the expression type(s) to match.
 446            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 447
 448        Returns:
 449            The generator object.
 450        """
 451        for expression in self.walk(bfs=bfs):
 452            if isinstance(expression, expression_types):
 453                yield expression
 454
 455    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 456        """
 457        Returns a nearest parent matching expression_types.
 458
 459        Args:
 460            expression_types: the expression type(s) to match.
 461
 462        Returns:
 463            The parent node.
 464        """
 465        ancestor = self.parent
 466        while ancestor and not isinstance(ancestor, expression_types):
 467            ancestor = ancestor.parent
 468        return ancestor  # type: ignore
 469
 470    @property
 471    def parent_select(self) -> t.Optional[Select]:
 472        """
 473        Returns the parent select statement.
 474        """
 475        return self.find_ancestor(Select)
 476
 477    @property
 478    def same_parent(self) -> bool:
 479        """Returns if the parent is the same class as itself."""
 480        return type(self.parent) is self.__class__
 481
 482    def root(self) -> Expression:
 483        """
 484        Returns the root expression of this tree.
 485        """
 486        expression = self
 487        while expression.parent:
 488            expression = expression.parent
 489        return expression
 490
 491    def walk(
 492        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
 493    ) -> t.Iterator[Expression]:
 494        """
 495        Returns a generator object which visits all nodes in this tree.
 496
 497        Args:
 498            bfs: if set to True the BFS traversal order will be applied,
 499                otherwise the DFS traversal will be used instead.
 500            prune: callable that returns True if the generator should stop traversing
 501                this branch of the tree.
 502
 503        Returns:
 504            the generator object.
 505        """
 506        if bfs:
 507            yield from self.bfs(prune=prune)
 508        else:
 509            yield from self.dfs(prune=prune)
 510
 511    def dfs(
 512        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 513    ) -> t.Iterator[Expression]:
 514        """
 515        Returns a generator object which visits all nodes in this tree in
 516        the DFS (Depth-first) order.
 517
 518        Returns:
 519            The generator object.
 520        """
 521        stack = [self]
 522
 523        while stack:
 524            node = stack.pop()
 525
 526            yield node
 527
 528            if prune and prune(node):
 529                continue
 530
 531            for v in node.iter_expressions(reverse=True):
 532                stack.append(v)
 533
 534    def bfs(
 535        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 536    ) -> t.Iterator[Expression]:
 537        """
 538        Returns a generator object which visits all nodes in this tree in
 539        the BFS (Breadth-first) order.
 540
 541        Returns:
 542            The generator object.
 543        """
 544        queue = deque([self])
 545
 546        while queue:
 547            node = queue.popleft()
 548
 549            yield node
 550
 551            if prune and prune(node):
 552                continue
 553
 554            for v in node.iter_expressions():
 555                queue.append(v)
 556
 557    def unnest(self):
 558        """
 559        Returns the first non parenthesis child or self.
 560        """
 561        expression = self
 562        while type(expression) is Paren:
 563            expression = expression.this
 564        return expression
 565
 566    def unalias(self):
 567        """
 568        Returns the inner expression if this is an Alias.
 569        """
 570        if isinstance(self, Alias):
 571            return self.this
 572        return self
 573
 574    def unnest_operands(self):
 575        """
 576        Returns unnested operands as a tuple.
 577        """
 578        return tuple(arg.unnest() for arg in self.iter_expressions())
 579
 580    def flatten(self, unnest=True):
 581        """
 582        Returns a generator which yields child nodes whose parents are the same class.
 583
 584        A AND B AND C -> [A, B, C]
 585        """
 586        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
 587            if type(node) is not self.__class__:
 588                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 589
 590    def __str__(self) -> str:
 591        return self.sql()
 592
 593    def __repr__(self) -> str:
 594        return _to_s(self)
 595
 596    def to_s(self) -> str:
 597        """
 598        Same as __repr__, but includes additional information which can be useful
 599        for debugging, like empty or missing args and the AST nodes' object IDs.
 600        """
 601        return _to_s(self, verbose=True)
 602
 603    def sql(self, dialect: DialectType = None, **opts) -> str:
 604        """
 605        Returns SQL string representation of this tree.
 606
 607        Args:
 608            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 609            opts: other `sqlglot.generator.Generator` options.
 610
 611        Returns:
 612            The SQL string.
 613        """
 614        from sqlglot.dialects import Dialect
 615
 616        return Dialect.get_or_raise(dialect).generate(self, **opts)
 617
 618    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
 619        """
 620        Visits all tree nodes (excluding already transformed ones)
 621        and applies the given transformation function to each node.
 622
 623        Args:
 624            fun: a function which takes a node as an argument and returns a
 625                new transformed node or the same node without modifications. If the function
 626                returns None, then the corresponding node will be removed from the syntax tree.
 627            copy: if set to True a new tree instance is constructed, otherwise the tree is
 628                modified in place.
 629
 630        Returns:
 631            The transformed tree.
 632        """
 633        root = None
 634        new_node = None
 635
 636        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
 637            parent, arg_key, index = node.parent, node.arg_key, node.index
 638            new_node = fun(node, *args, **kwargs)
 639
 640            if not root:
 641                root = new_node
 642            elif parent and arg_key and new_node is not node:
 643                parent.set(arg_key, new_node, index)
 644
 645        assert root
 646        return root.assert_is(Expression)
 647
 648    @t.overload
 649    def replace(self, expression: E) -> E: ...
 650
 651    @t.overload
 652    def replace(self, expression: None) -> None: ...
 653
 654    def replace(self, expression):
 655        """
 656        Swap out this expression with a new expression.
 657
 658        For example::
 659
 660            >>> tree = Select().select("x").from_("tbl")
 661            >>> tree.find(Column).replace(column("y"))
 662            Column(
 663              this=Identifier(this=y, quoted=False))
 664            >>> tree.sql()
 665            'SELECT y FROM tbl'
 666
 667        Args:
 668            expression: new node
 669
 670        Returns:
 671            The new expression or expressions.
 672        """
 673        parent = self.parent
 674
 675        if not parent or parent is expression:
 676            return expression
 677
 678        key = self.arg_key
 679        value = parent.args.get(key)
 680
 681        if type(expression) is list and isinstance(value, Expression):
 682            # We are trying to replace an Expression with a list, so it's assumed that
 683            # the intention was to really replace the parent of this expression.
 684            value.parent.replace(expression)
 685        else:
 686            parent.set(key, expression, self.index)
 687
 688        if expression is not self:
 689            self.parent = None
 690            self.arg_key = None
 691            self.index = None
 692
 693        return expression
 694
 695    def pop(self: E) -> E:
 696        """
 697        Remove this expression from its AST.
 698
 699        Returns:
 700            The popped expression.
 701        """
 702        self.replace(None)
 703        return self
 704
 705    def assert_is(self, type_: t.Type[E]) -> E:
 706        """
 707        Assert that this `Expression` is an instance of `type_`.
 708
 709        If it is NOT an instance of `type_`, this raises an assertion error.
 710        Otherwise, this returns this expression.
 711
 712        Examples:
 713            This is useful for type security in chained expressions:
 714
 715            >>> import sqlglot
 716            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 717            'SELECT x, z FROM y'
 718        """
 719        if not isinstance(self, type_):
 720            raise AssertionError(f"{self} is not {type_}.")
 721        return self
 722
 723    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 724        """
 725        Checks if this expression is valid (e.g. all mandatory args are set).
 726
 727        Args:
 728            args: a sequence of values that were used to instantiate a Func expression. This is used
 729                to check that the provided arguments don't exceed the function argument limit.
 730
 731        Returns:
 732            A list of error messages for all possible errors that were found.
 733        """
 734        errors: t.List[str] = []
 735
 736        for k in self.args:
 737            if k not in self.arg_types:
 738                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 739        for k, mandatory in self.arg_types.items():
 740            v = self.args.get(k)
 741            if mandatory and (v is None or (isinstance(v, list) and not v)):
 742                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 743
 744        if (
 745            args
 746            and isinstance(self, Func)
 747            and len(args) > len(self.arg_types)
 748            and not self.is_var_len_args
 749        ):
 750            errors.append(
 751                f"The number of provided arguments ({len(args)}) is greater than "
 752                f"the maximum number of supported arguments ({len(self.arg_types)})"
 753            )
 754
 755        return errors
 756
 757    def dump(self):
 758        """
 759        Dump this Expression to a JSON-serializable dict.
 760        """
 761        from sqlglot.serde import dump
 762
 763        return dump(self)
 764
 765    @classmethod
 766    def load(cls, obj):
 767        """
 768        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 769        """
 770        from sqlglot.serde import load
 771
 772        return load(obj)
 773
 774    def and_(
 775        self,
 776        *expressions: t.Optional[ExpOrStr],
 777        dialect: DialectType = None,
 778        copy: bool = True,
 779        wrap: bool = True,
 780        **opts,
 781    ) -> Condition:
 782        """
 783        AND this condition with one or multiple expressions.
 784
 785        Example:
 786            >>> condition("x=1").and_("y=1").sql()
 787            'x = 1 AND y = 1'
 788
 789        Args:
 790            *expressions: the SQL code strings to parse.
 791                If an `Expression` instance is passed, it will be used as-is.
 792            dialect: the dialect used to parse the input expression.
 793            copy: whether to copy the involved expressions (only applies to Expressions).
 794            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 795                precedence issues, but can be turned off when the produced AST is too deep and
 796                causes recursion-related issues.
 797            opts: other options to use to parse the input expressions.
 798
 799        Returns:
 800            The new And condition.
 801        """
 802        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 803
 804    def or_(
 805        self,
 806        *expressions: t.Optional[ExpOrStr],
 807        dialect: DialectType = None,
 808        copy: bool = True,
 809        wrap: bool = True,
 810        **opts,
 811    ) -> Condition:
 812        """
 813        OR this condition with one or multiple expressions.
 814
 815        Example:
 816            >>> condition("x=1").or_("y=1").sql()
 817            'x = 1 OR y = 1'
 818
 819        Args:
 820            *expressions: the SQL code strings to parse.
 821                If an `Expression` instance is passed, it will be used as-is.
 822            dialect: the dialect used to parse the input expression.
 823            copy: whether to copy the involved expressions (only applies to Expressions).
 824            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 825                precedence issues, but can be turned off when the produced AST is too deep and
 826                causes recursion-related issues.
 827            opts: other options to use to parse the input expressions.
 828
 829        Returns:
 830            The new Or condition.
 831        """
 832        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 833
 834    def not_(self, copy: bool = True):
 835        """
 836        Wrap this condition with NOT.
 837
 838        Example:
 839            >>> condition("x=1").not_().sql()
 840            'NOT x = 1'
 841
 842        Args:
 843            copy: whether to copy this object.
 844
 845        Returns:
 846            The new Not instance.
 847        """
 848        return not_(self, copy=copy)
 849
 850    def as_(
 851        self,
 852        alias: str | Identifier,
 853        quoted: t.Optional[bool] = None,
 854        dialect: DialectType = None,
 855        copy: bool = True,
 856        **opts,
 857    ) -> Alias:
 858        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 859
 860    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 861        this = self.copy()
 862        other = convert(other, copy=True)
 863        if not isinstance(this, klass) and not isinstance(other, klass):
 864            this = _wrap(this, Binary)
 865            other = _wrap(other, Binary)
 866        if reverse:
 867            return klass(this=other, expression=this)
 868        return klass(this=this, expression=other)
 869
 870    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 871        return Bracket(
 872            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 873        )
 874
 875    def __iter__(self) -> t.Iterator:
 876        if "expressions" in self.arg_types:
 877            return iter(self.args.get("expressions") or [])
 878        # We define this because __getitem__ converts Expression into an iterable, which is
 879        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 880        # See: https://peps.python.org/pep-0234/
 881        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 882
 883    def isin(
 884        self,
 885        *expressions: t.Any,
 886        query: t.Optional[ExpOrStr] = None,
 887        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 888        copy: bool = True,
 889        **opts,
 890    ) -> In:
 891        subquery = maybe_parse(query, copy=copy, **opts) if query else None
 892        if subquery and not isinstance(subquery, Subquery):
 893            subquery = subquery.subquery(copy=False)
 894
 895        return In(
 896            this=maybe_copy(self, copy),
 897            expressions=[convert(e, copy=copy) for e in expressions],
 898            query=subquery,
 899            unnest=(
 900                Unnest(
 901                    expressions=[
 902                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 903                        for e in ensure_list(unnest)
 904                    ]
 905                )
 906                if unnest
 907                else None
 908            ),
 909        )
 910
 911    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 912        return Between(
 913            this=maybe_copy(self, copy),
 914            low=convert(low, copy=copy, **opts),
 915            high=convert(high, copy=copy, **opts),
 916        )
 917
 918    def is_(self, other: ExpOrStr) -> Is:
 919        return self._binop(Is, other)
 920
 921    def like(self, other: ExpOrStr) -> Like:
 922        return self._binop(Like, other)
 923
 924    def ilike(self, other: ExpOrStr) -> ILike:
 925        return self._binop(ILike, other)
 926
 927    def eq(self, other: t.Any) -> EQ:
 928        return self._binop(EQ, other)
 929
 930    def neq(self, other: t.Any) -> NEQ:
 931        return self._binop(NEQ, other)
 932
 933    def rlike(self, other: ExpOrStr) -> RegexpLike:
 934        return self._binop(RegexpLike, other)
 935
 936    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 937        div = self._binop(Div, other)
 938        div.args["typed"] = typed
 939        div.args["safe"] = safe
 940        return div
 941
 942    def asc(self, nulls_first: bool = True) -> Ordered:
 943        return Ordered(this=self.copy(), nulls_first=nulls_first)
 944
 945    def desc(self, nulls_first: bool = False) -> Ordered:
 946        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 947
 948    def __lt__(self, other: t.Any) -> LT:
 949        return self._binop(LT, other)
 950
 951    def __le__(self, other: t.Any) -> LTE:
 952        return self._binop(LTE, other)
 953
 954    def __gt__(self, other: t.Any) -> GT:
 955        return self._binop(GT, other)
 956
 957    def __ge__(self, other: t.Any) -> GTE:
 958        return self._binop(GTE, other)
 959
 960    def __add__(self, other: t.Any) -> Add:
 961        return self._binop(Add, other)
 962
 963    def __radd__(self, other: t.Any) -> Add:
 964        return self._binop(Add, other, reverse=True)
 965
 966    def __sub__(self, other: t.Any) -> Sub:
 967        return self._binop(Sub, other)
 968
 969    def __rsub__(self, other: t.Any) -> Sub:
 970        return self._binop(Sub, other, reverse=True)
 971
 972    def __mul__(self, other: t.Any) -> Mul:
 973        return self._binop(Mul, other)
 974
 975    def __rmul__(self, other: t.Any) -> Mul:
 976        return self._binop(Mul, other, reverse=True)
 977
 978    def __truediv__(self, other: t.Any) -> Div:
 979        return self._binop(Div, other)
 980
 981    def __rtruediv__(self, other: t.Any) -> Div:
 982        return self._binop(Div, other, reverse=True)
 983
 984    def __floordiv__(self, other: t.Any) -> IntDiv:
 985        return self._binop(IntDiv, other)
 986
 987    def __rfloordiv__(self, other: t.Any) -> IntDiv:
 988        return self._binop(IntDiv, other, reverse=True)
 989
 990    def __mod__(self, other: t.Any) -> Mod:
 991        return self._binop(Mod, other)
 992
 993    def __rmod__(self, other: t.Any) -> Mod:
 994        return self._binop(Mod, other, reverse=True)
 995
 996    def __pow__(self, other: t.Any) -> Pow:
 997        return self._binop(Pow, other)
 998
 999    def __rpow__(self, other: t.Any) -> Pow:
1000        return self._binop(Pow, other, reverse=True)
1001
1002    def __and__(self, other: t.Any) -> And:
1003        return self._binop(And, other)
1004
1005    def __rand__(self, other: t.Any) -> And:
1006        return self._binop(And, other, reverse=True)
1007
1008    def __or__(self, other: t.Any) -> Or:
1009        return self._binop(Or, other)
1010
1011    def __ror__(self, other: t.Any) -> Or:
1012        return self._binop(Or, other, reverse=True)
1013
1014    def __neg__(self) -> Neg:
1015        return Neg(this=_wrap(self.copy(), Binary))
1016
1017    def __invert__(self) -> Not:
1018        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 the arguments (child nodes) 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.
  • index: the index of an expression if it is inside of a list argument in its parent.
  • 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 sqlglot.expressions.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)
106    def __init__(self, **args: t.Any):
107        self.args: t.Dict[str, t.Any] = args
108        self.parent: t.Optional[Expression] = None
109        self.arg_key: t.Optional[str] = None
110        self.index: t.Optional[int] = None
111        self.comments: t.Optional[t.List[str]] = None
112        self._type: t.Optional[DataType] = None
113        self._meta: t.Optional[t.Dict[str, t.Any]] = None
114        self._hash: t.Optional[int] = None
115
116        for arg_key, value in self.args.items():
117            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
hashable_args: Any
122    @property
123    def hashable_args(self) -> t.Any:
124        return frozenset(
125            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
126            for k, v in self.args.items()
127            if not (v is None or v is False or (type(v) is list and not v))
128        )
this: Any
136    @property
137    def this(self) -> t.Any:
138        """
139        Retrieves the argument with key "this".
140        """
141        return self.args.get("this")

Retrieves the argument with key "this".

expression: Any
143    @property
144    def expression(self) -> t.Any:
145        """
146        Retrieves the argument with key "expression".
147        """
148        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
150    @property
151    def expressions(self) -> t.List[t.Any]:
152        """
153        Retrieves the argument with key "expressions".
154        """
155        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
157    def text(self, key) -> str:
158        """
159        Returns a textual representation of the argument corresponding to "key". This can only be used
160        for args that are strings or leaf Expression instances, such as identifiers and literals.
161        """
162        field = self.args.get(key)
163        if isinstance(field, str):
164            return field
165        if isinstance(field, (Identifier, Literal, Var)):
166            return field.this
167        if isinstance(field, (Star, Null)):
168            return field.name
169        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
171    @property
172    def is_string(self) -> bool:
173        """
174        Checks whether a Literal expression is a string.
175        """
176        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
178    @property
179    def is_number(self) -> bool:
180        """
181        Checks whether a Literal expression is a number.
182        """
183        return (isinstance(self, Literal) and not self.args["is_string"]) or (
184            isinstance(self, Neg) and self.this.is_number
185        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
187    def to_py(self) -> t.Any:
188        """
189        Returns a Python object equivalent of the SQL node.
190        """
191        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
193    @property
194    def is_int(self) -> bool:
195        """
196        Checks whether an expression is an integer.
197        """
198        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
200    @property
201    def is_star(self) -> bool:
202        """Checks whether an expression is a star."""
203        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
205    @property
206    def alias(self) -> str:
207        """
208        Returns the alias of the expression, or an empty string if it's not aliased.
209        """
210        if isinstance(self.args.get("alias"), TableAlias):
211            return self.args["alias"].name
212        return self.text("alias")

Returns the alias of the expression, or an empty string if it's not aliased.

alias_column_names: List[str]
214    @property
215    def alias_column_names(self) -> t.List[str]:
216        table_alias = self.args.get("alias")
217        if not table_alias:
218            return []
219        return [c.name for c in table_alias.args.get("columns") or []]
name: str
221    @property
222    def name(self) -> str:
223        return self.text("this")
alias_or_name: str
225    @property
226    def alias_or_name(self) -> str:
227        return self.alias or self.name
output_name: str
229    @property
230    def output_name(self) -> str:
231        """
232        Name of the output column if this expression is a selection.
233
234        If the Expression has no output name, an empty string is returned.
235
236        Example:
237            >>> from sqlglot import parse_one
238            >>> parse_one("SELECT a").expressions[0].output_name
239            'a'
240            >>> parse_one("SELECT b AS c").expressions[0].output_name
241            'c'
242            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
243            ''
244        """
245        return ""

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]
247    @property
248    def type(self) -> t.Optional[DataType]:
249        return self._type
def is_type(self, *dtypes) -> bool:
257    def is_type(self, *dtypes) -> bool:
258        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
260    def is_leaf(self) -> bool:
261        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
263    @property
264    def meta(self) -> t.Dict[str, t.Any]:
265        if self._meta is None:
266            self._meta = {}
267        return self._meta
def copy(self) -> typing_extensions.Self:
303    def copy(self) -> Self:
304        """
305        Returns a deep copy of the expression.
306        """
307        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
309    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
310        if self.comments is None:
311            self.comments = []
312
313        if comments:
314            for comment in comments:
315                _, *meta = comment.split(SQLGLOT_META)
316                if meta:
317                    for kv in "".join(meta).split(","):
318                        k, *v = kv.split("=")
319                        value = v[0].strip() if v else True
320                        self.meta[k.strip()] = to_bool(value)
321
322                if not prepend:
323                    self.comments.append(comment)
324
325            if prepend:
326                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
328    def pop_comments(self) -> t.List[str]:
329        comments = self.comments or []
330        self.comments = None
331        return comments
def append(self, arg_key: str, value: Any) -> None:
333    def append(self, arg_key: str, value: t.Any) -> None:
334        """
335        Appends value to arg_key if it's a list or sets it as a new list.
336
337        Args:
338            arg_key (str): name of the list expression arg
339            value (Any): value to append to the list
340        """
341        if type(self.args.get(arg_key)) is not list:
342            self.args[arg_key] = []
343        self._set_parent(arg_key, value)
344        values = self.args[arg_key]
345        if hasattr(value, "parent"):
346            value.index = len(values)
347        values.append(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, index: Optional[int] = None, overwrite: bool = True) -> None:
349    def set(
350        self,
351        arg_key: str,
352        value: t.Any,
353        index: t.Optional[int] = None,
354        overwrite: bool = True,
355    ) -> None:
356        """
357        Sets arg_key to value.
358
359        Args:
360            arg_key: name of the expression arg.
361            value: value to set the arg to.
362            index: if the arg is a list, this specifies what position to add the value in it.
363            overwrite: assuming an index is given, this determines whether to overwrite the
364                list entry instead of only inserting a new value (i.e., like list.insert).
365        """
366        if index is not None:
367            expressions = self.args.get(arg_key) or []
368
369            if seq_get(expressions, index) is None:
370                return
371            if value is None:
372                expressions.pop(index)
373                for v in expressions[index:]:
374                    v.index = v.index - 1
375                return
376
377            if isinstance(value, list):
378                expressions.pop(index)
379                expressions[index:index] = value
380            elif overwrite:
381                expressions[index] = value
382            else:
383                expressions.insert(index, value)
384
385            value = expressions
386        elif value is None:
387            self.args.pop(arg_key, None)
388            return
389
390        self.args[arg_key] = value
391        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
  • overwrite: assuming an index is given, this determines whether to overwrite the list entry instead of only inserting a new value (i.e., like list.insert).
depth: int
405    @property
406    def depth(self) -> int:
407        """
408        Returns the depth of this tree.
409        """
410        if self.parent:
411            return self.parent.depth + 1
412        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
414    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
415        """Yields the key and expression for all arguments, exploding list args."""
416        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
417            if type(vs) is list:
418                for v in reversed(vs) if reverse else vs:  # type: ignore
419                    if hasattr(v, "parent"):
420                        yield v
421            else:
422                if hasattr(vs, "parent"):
423                    yield vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
425    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
426        """
427        Returns the first node in this tree which matches at least one of
428        the specified types.
429
430        Args:
431            expression_types: the expression type(s) to match.
432            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
433
434        Returns:
435            The node which matches the criteria or None if no such node was found.
436        """
437        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]:
439    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
440        """
441        Returns a generator object which visits all nodes in this tree and only
442        yields those that match at least one of the specified expression types.
443
444        Args:
445            expression_types: the expression type(s) to match.
446            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
447
448        Returns:
449            The generator object.
450        """
451        for expression in self.walk(bfs=bfs):
452            if isinstance(expression, expression_types):
453                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]:
455    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
456        """
457        Returns a nearest parent matching expression_types.
458
459        Args:
460            expression_types: the expression type(s) to match.
461
462        Returns:
463            The parent node.
464        """
465        ancestor = self.parent
466        while ancestor and not isinstance(ancestor, expression_types):
467            ancestor = ancestor.parent
468        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]
470    @property
471    def parent_select(self) -> t.Optional[Select]:
472        """
473        Returns the parent select statement.
474        """
475        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
477    @property
478    def same_parent(self) -> bool:
479        """Returns if the parent is the same class as itself."""
480        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
482    def root(self) -> Expression:
483        """
484        Returns the root expression of this tree.
485        """
486        expression = self
487        while expression.parent:
488            expression = expression.parent
489        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
491    def walk(
492        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
493    ) -> t.Iterator[Expression]:
494        """
495        Returns a generator object which visits all nodes in this tree.
496
497        Args:
498            bfs: if set to True the BFS traversal order will be applied,
499                otherwise the DFS traversal will be used instead.
500            prune: callable that returns True if the generator should stop traversing
501                this branch of the tree.
502
503        Returns:
504            the generator object.
505        """
506        if bfs:
507            yield from self.bfs(prune=prune)
508        else:
509            yield from self.dfs(prune=prune)

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

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

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
511    def dfs(
512        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
513    ) -> t.Iterator[Expression]:
514        """
515        Returns a generator object which visits all nodes in this tree in
516        the DFS (Depth-first) order.
517
518        Returns:
519            The generator object.
520        """
521        stack = [self]
522
523        while stack:
524            node = stack.pop()
525
526            yield node
527
528            if prune and prune(node):
529                continue
530
531            for v in node.iter_expressions(reverse=True):
532                stack.append(v)

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: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
534    def bfs(
535        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
536    ) -> t.Iterator[Expression]:
537        """
538        Returns a generator object which visits all nodes in this tree in
539        the BFS (Breadth-first) order.
540
541        Returns:
542            The generator object.
543        """
544        queue = deque([self])
545
546        while queue:
547            node = queue.popleft()
548
549            yield node
550
551            if prune and prune(node):
552                continue
553
554            for v in node.iter_expressions():
555                queue.append(v)

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

Returns:

The generator object.

def unnest(self):
557    def unnest(self):
558        """
559        Returns the first non parenthesis child or self.
560        """
561        expression = self
562        while type(expression) is Paren:
563            expression = expression.this
564        return expression

Returns the first non parenthesis child or self.

def unalias(self):
566    def unalias(self):
567        """
568        Returns the inner expression if this is an Alias.
569        """
570        if isinstance(self, Alias):
571            return self.this
572        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
574    def unnest_operands(self):
575        """
576        Returns unnested operands as a tuple.
577        """
578        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
580    def flatten(self, unnest=True):
581        """
582        Returns a generator which yields child nodes whose parents are the same class.
583
584        A AND B AND C -> [A, B, C]
585        """
586        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
587            if type(node) is not self.__class__:
588                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
596    def to_s(self) -> str:
597        """
598        Same as __repr__, but includes additional information which can be useful
599        for debugging, like empty or missing args and the AST nodes' object IDs.
600        """
601        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> str:
603    def sql(self, dialect: DialectType = None, **opts) -> str:
604        """
605        Returns SQL string representation of this tree.
606
607        Args:
608            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
609            opts: other `sqlglot.generator.Generator` options.
610
611        Returns:
612            The SQL string.
613        """
614        from sqlglot.dialects import Dialect
615
616        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: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
618    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
619        """
620        Visits all tree nodes (excluding already transformed ones)
621        and applies the given transformation function to each node.
622
623        Args:
624            fun: a function which takes a node as an argument and returns a
625                new transformed node or the same node without modifications. If the function
626                returns None, then the corresponding node will be removed from the syntax tree.
627            copy: if set to True a new tree instance is constructed, otherwise the tree is
628                modified in place.
629
630        Returns:
631            The transformed tree.
632        """
633        root = None
634        new_node = None
635
636        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
637            parent, arg_key, index = node.parent, node.arg_key, node.index
638            new_node = fun(node, *args, **kwargs)
639
640            if not root:
641                root = new_node
642            elif parent and arg_key and new_node is not node:
643                parent.set(arg_key, new_node, index)
644
645        assert root
646        return root.assert_is(Expression)

Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun: 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: 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):
654    def replace(self, expression):
655        """
656        Swap out this expression with a new expression.
657
658        For example::
659
660            >>> tree = Select().select("x").from_("tbl")
661            >>> tree.find(Column).replace(column("y"))
662            Column(
663              this=Identifier(this=y, quoted=False))
664            >>> tree.sql()
665            'SELECT y FROM tbl'
666
667        Args:
668            expression: new node
669
670        Returns:
671            The new expression or expressions.
672        """
673        parent = self.parent
674
675        if not parent or parent is expression:
676            return expression
677
678        key = self.arg_key
679        value = parent.args.get(key)
680
681        if type(expression) is list and isinstance(value, Expression):
682            # We are trying to replace an Expression with a list, so it's assumed that
683            # the intention was to really replace the parent of this expression.
684            value.parent.replace(expression)
685        else:
686            parent.set(key, expression, self.index)
687
688        if expression is not self:
689            self.parent = None
690            self.arg_key = None
691            self.index = None
692
693        return expression

Swap out this expression with a new expression.

For example::

>>> tree = Select().select("x").from_("tbl")
>>> tree.find(Column).replace(column("y"))
Column(
  this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
695    def pop(self: E) -> E:
696        """
697        Remove this expression from its AST.
698
699        Returns:
700            The popped expression.
701        """
702        self.replace(None)
703        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
705    def assert_is(self, type_: t.Type[E]) -> E:
706        """
707        Assert that this `Expression` is an instance of `type_`.
708
709        If it is NOT an instance of `type_`, this raises an assertion error.
710        Otherwise, this returns this expression.
711
712        Examples:
713            This is useful for type security in chained expressions:
714
715            >>> import sqlglot
716            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
717            'SELECT x, z FROM y'
718        """
719        if not isinstance(self, type_):
720            raise AssertionError(f"{self} is not {type_}.")
721        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]:
723    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
724        """
725        Checks if this expression is valid (e.g. all mandatory args are set).
726
727        Args:
728            args: a sequence of values that were used to instantiate a Func expression. This is used
729                to check that the provided arguments don't exceed the function argument limit.
730
731        Returns:
732            A list of error messages for all possible errors that were found.
733        """
734        errors: t.List[str] = []
735
736        for k in self.args:
737            if k not in self.arg_types:
738                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
739        for k, mandatory in self.arg_types.items():
740            v = self.args.get(k)
741            if mandatory and (v is None or (isinstance(v, list) and not v)):
742                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
743
744        if (
745            args
746            and isinstance(self, Func)
747            and len(args) > len(self.arg_types)
748            and not self.is_var_len_args
749        ):
750            errors.append(
751                f"The number of provided arguments ({len(args)}) is greater than "
752                f"the maximum number of supported arguments ({len(self.arg_types)})"
753            )
754
755        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):
757    def dump(self):
758        """
759        Dump this Expression to a JSON-serializable dict.
760        """
761        from sqlglot.serde import dump
762
763        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
765    @classmethod
766    def load(cls, obj):
767        """
768        Load a dict (as returned by `Expression.dump`) into an Expression instance.
769        """
770        from sqlglot.serde import load
771
772        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
774    def and_(
775        self,
776        *expressions: t.Optional[ExpOrStr],
777        dialect: DialectType = None,
778        copy: bool = True,
779        wrap: bool = True,
780        **opts,
781    ) -> Condition:
782        """
783        AND this condition with one or multiple expressions.
784
785        Example:
786            >>> condition("x=1").and_("y=1").sql()
787            'x = 1 AND y = 1'
788
789        Args:
790            *expressions: the SQL code strings to parse.
791                If an `Expression` instance is passed, it will be used as-is.
792            dialect: the dialect used to parse the input expression.
793            copy: whether to copy the involved expressions (only applies to Expressions).
794            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
795                precedence issues, but can be turned off when the produced AST is too deep and
796                causes recursion-related issues.
797            opts: other options to use to parse the input expressions.
798
799        Returns:
800            The new And condition.
801        """
802        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **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 to copy the involved expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • 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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
804    def or_(
805        self,
806        *expressions: t.Optional[ExpOrStr],
807        dialect: DialectType = None,
808        copy: bool = True,
809        wrap: bool = True,
810        **opts,
811    ) -> Condition:
812        """
813        OR this condition with one or multiple expressions.
814
815        Example:
816            >>> condition("x=1").or_("y=1").sql()
817            'x = 1 OR y = 1'
818
819        Args:
820            *expressions: the SQL code strings to parse.
821                If an `Expression` instance is passed, it will be used as-is.
822            dialect: the dialect used to parse the input expression.
823            copy: whether to copy the involved expressions (only applies to Expressions).
824            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
825                precedence issues, but can be turned off when the produced AST is too deep and
826                causes recursion-related issues.
827            opts: other options to use to parse the input expressions.
828
829        Returns:
830            The new Or condition.
831        """
832        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **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 to copy the involved expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
834    def not_(self, copy: bool = True):
835        """
836        Wrap this condition with NOT.
837
838        Example:
839            >>> condition("x=1").not_().sql()
840            'NOT x = 1'
841
842        Args:
843            copy: whether to copy this object.
844
845        Returns:
846            The new Not instance.
847        """
848        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether 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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
850    def as_(
851        self,
852        alias: str | Identifier,
853        quoted: t.Optional[bool] = None,
854        dialect: DialectType = None,
855        copy: bool = True,
856        **opts,
857    ) -> Alias:
858        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:
883    def isin(
884        self,
885        *expressions: t.Any,
886        query: t.Optional[ExpOrStr] = None,
887        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
888        copy: bool = True,
889        **opts,
890    ) -> In:
891        subquery = maybe_parse(query, copy=copy, **opts) if query else None
892        if subquery and not isinstance(subquery, Subquery):
893            subquery = subquery.subquery(copy=False)
894
895        return In(
896            this=maybe_copy(self, copy),
897            expressions=[convert(e, copy=copy) for e in expressions],
898            query=subquery,
899            unnest=(
900                Unnest(
901                    expressions=[
902                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
903                        for e in ensure_list(unnest)
904                    ]
905                )
906                if unnest
907                else None
908            ),
909        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
911    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
912        return Between(
913            this=maybe_copy(self, copy),
914            low=convert(low, copy=copy, **opts),
915            high=convert(high, copy=copy, **opts),
916        )
def is_( self, other: Union[str, Expression]) -> Is:
918    def is_(self, other: ExpOrStr) -> Is:
919        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
921    def like(self, other: ExpOrStr) -> Like:
922        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
924    def ilike(self, other: ExpOrStr) -> ILike:
925        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
927    def eq(self, other: t.Any) -> EQ:
928        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
930    def neq(self, other: t.Any) -> NEQ:
931        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
933    def rlike(self, other: ExpOrStr) -> RegexpLike:
934        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
936    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
937        div = self._binop(Div, other)
938        div.args["typed"] = typed
939        div.args["safe"] = safe
940        return div
def asc(self, nulls_first: bool = True) -> Ordered:
942    def asc(self, nulls_first: bool = True) -> Ordered:
943        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
945    def desc(self, nulls_first: bool = False) -> Ordered:
946        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
1029class Condition(Expression):
1030    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
1037class DerivedTable(Expression):
1038    @property
1039    def selects(self) -> t.List[Expression]:
1040        return self.this.selects if isinstance(self.this, Query) else []
1041
1042    @property
1043    def named_selects(self) -> t.List[str]:
1044        return [select.output_name for select in self.selects]
selects: List[Expression]
1038    @property
1039    def selects(self) -> t.List[Expression]:
1040        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1042    @property
1043    def named_selects(self) -> t.List[str]:
1044        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1047class Query(Expression):
1048    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1049        """
1050        Returns a `Subquery` that wraps around this query.
1051
1052        Example:
1053            >>> subquery = Select().select("x").from_("tbl").subquery()
1054            >>> Select().select("x").from_(subquery).sql()
1055            'SELECT x FROM (SELECT x FROM tbl)'
1056
1057        Args:
1058            alias: an optional alias for the subquery.
1059            copy: if `False`, modify this expression instance in-place.
1060        """
1061        instance = maybe_copy(self, copy)
1062        if not isinstance(alias, Expression):
1063            alias = TableAlias(this=to_identifier(alias)) if alias else None
1064
1065        return Subquery(this=instance, alias=alias)
1066
1067    def limit(
1068        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1069    ) -> Q:
1070        """
1071        Adds a LIMIT clause to this query.
1072
1073        Example:
1074            >>> select("1").union(select("1")).limit(1).sql()
1075            'SELECT 1 UNION SELECT 1 LIMIT 1'
1076
1077        Args:
1078            expression: the SQL code string to parse.
1079                This can also be an integer.
1080                If a `Limit` instance is passed, it will be used as-is.
1081                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1082            dialect: the dialect used to parse the input expression.
1083            copy: if `False`, modify this expression instance in-place.
1084            opts: other options to use to parse the input expressions.
1085
1086        Returns:
1087            A limited Select expression.
1088        """
1089        return _apply_builder(
1090            expression=expression,
1091            instance=self,
1092            arg="limit",
1093            into=Limit,
1094            prefix="LIMIT",
1095            dialect=dialect,
1096            copy=copy,
1097            into_arg="expression",
1098            **opts,
1099        )
1100
1101    def offset(
1102        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1103    ) -> Q:
1104        """
1105        Set the OFFSET expression.
1106
1107        Example:
1108            >>> Select().from_("tbl").select("x").offset(10).sql()
1109            'SELECT x FROM tbl OFFSET 10'
1110
1111        Args:
1112            expression: the SQL code string to parse.
1113                This can also be an integer.
1114                If a `Offset` instance is passed, this is used as-is.
1115                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1116            dialect: the dialect used to parse the input expression.
1117            copy: if `False`, modify this expression instance in-place.
1118            opts: other options to use to parse the input expressions.
1119
1120        Returns:
1121            The modified Select expression.
1122        """
1123        return _apply_builder(
1124            expression=expression,
1125            instance=self,
1126            arg="offset",
1127            into=Offset,
1128            prefix="OFFSET",
1129            dialect=dialect,
1130            copy=copy,
1131            into_arg="expression",
1132            **opts,
1133        )
1134
1135    def order_by(
1136        self: Q,
1137        *expressions: t.Optional[ExpOrStr],
1138        append: bool = True,
1139        dialect: DialectType = None,
1140        copy: bool = True,
1141        **opts,
1142    ) -> Q:
1143        """
1144        Set the ORDER BY expression.
1145
1146        Example:
1147            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1148            'SELECT x FROM tbl ORDER BY x DESC'
1149
1150        Args:
1151            *expressions: the SQL code strings to parse.
1152                If a `Group` instance is passed, this is used as-is.
1153                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1154            append: if `True`, add to any existing expressions.
1155                Otherwise, this flattens all the `Order` expression into a single expression.
1156            dialect: the dialect used to parse the input expression.
1157            copy: if `False`, modify this expression instance in-place.
1158            opts: other options to use to parse the input expressions.
1159
1160        Returns:
1161            The modified Select expression.
1162        """
1163        return _apply_child_list_builder(
1164            *expressions,
1165            instance=self,
1166            arg="order",
1167            append=append,
1168            copy=copy,
1169            prefix="ORDER BY",
1170            into=Order,
1171            dialect=dialect,
1172            **opts,
1173        )
1174
1175    @property
1176    def ctes(self) -> t.List[CTE]:
1177        """Returns a list of all the CTEs attached to this query."""
1178        with_ = self.args.get("with")
1179        return with_.expressions if with_ else []
1180
1181    @property
1182    def selects(self) -> t.List[Expression]:
1183        """Returns the query's projections."""
1184        raise NotImplementedError("Query objects must implement `selects`")
1185
1186    @property
1187    def named_selects(self) -> t.List[str]:
1188        """Returns the output names of the query's projections."""
1189        raise NotImplementedError("Query objects must implement `named_selects`")
1190
1191    def select(
1192        self: Q,
1193        *expressions: t.Optional[ExpOrStr],
1194        append: bool = True,
1195        dialect: DialectType = None,
1196        copy: bool = True,
1197        **opts,
1198    ) -> Q:
1199        """
1200        Append to or set the SELECT expressions.
1201
1202        Example:
1203            >>> Select().select("x", "y").sql()
1204            'SELECT x, y'
1205
1206        Args:
1207            *expressions: the SQL code strings to parse.
1208                If an `Expression` instance is passed, it will be used as-is.
1209            append: if `True`, add to any existing expressions.
1210                Otherwise, this resets the expressions.
1211            dialect: the dialect used to parse the input expressions.
1212            copy: if `False`, modify this expression instance in-place.
1213            opts: other options to use to parse the input expressions.
1214
1215        Returns:
1216            The modified Query expression.
1217        """
1218        raise NotImplementedError("Query objects must implement `select`")
1219
1220    def with_(
1221        self: Q,
1222        alias: ExpOrStr,
1223        as_: ExpOrStr,
1224        recursive: t.Optional[bool] = None,
1225        materialized: t.Optional[bool] = None,
1226        append: bool = True,
1227        dialect: DialectType = None,
1228        copy: bool = True,
1229        scalar: bool = False,
1230        **opts,
1231    ) -> Q:
1232        """
1233        Append to or set the common table expressions.
1234
1235        Example:
1236            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1237            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1238
1239        Args:
1240            alias: the SQL code string to parse as the table name.
1241                If an `Expression` instance is passed, this is used as-is.
1242            as_: the SQL code string to parse as the table expression.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1245            materialized: set the MATERIALIZED part of the expression.
1246            append: if `True`, add to any existing expressions.
1247                Otherwise, this resets the expressions.
1248            dialect: the dialect used to parse the input expression.
1249            copy: if `False`, modify this expression instance in-place.
1250            scalar: if `True`, this is a scalar common table expression.
1251            opts: other options to use to parse the input expressions.
1252
1253        Returns:
1254            The modified expression.
1255        """
1256        return _apply_cte_builder(
1257            self,
1258            alias,
1259            as_,
1260            recursive=recursive,
1261            materialized=materialized,
1262            append=append,
1263            dialect=dialect,
1264            copy=copy,
1265            scalar=scalar,
1266            **opts,
1267        )
1268
1269    def union(
1270        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1271    ) -> Union:
1272        """
1273        Builds a UNION expression.
1274
1275        Example:
1276            >>> import sqlglot
1277            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1278            'SELECT * FROM foo UNION SELECT * FROM bla'
1279
1280        Args:
1281            expressions: the SQL code strings.
1282                If `Expression` instances are passed, they will be used as-is.
1283            distinct: set the DISTINCT flag if and only if this is true.
1284            dialect: the dialect used to parse the input expression.
1285            opts: other options to use to parse the input expressions.
1286
1287        Returns:
1288            The new Union expression.
1289        """
1290        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1291
1292    def intersect(
1293        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1294    ) -> Intersect:
1295        """
1296        Builds an INTERSECT expression.
1297
1298        Example:
1299            >>> import sqlglot
1300            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1301            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1302
1303        Args:
1304            expressions: the SQL code strings.
1305                If `Expression` instances are passed, they will be used as-is.
1306            distinct: set the DISTINCT flag if and only if this is true.
1307            dialect: the dialect used to parse the input expression.
1308            opts: other options to use to parse the input expressions.
1309
1310        Returns:
1311            The new Intersect expression.
1312        """
1313        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1314
1315    def except_(
1316        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1317    ) -> Except:
1318        """
1319        Builds an EXCEPT expression.
1320
1321        Example:
1322            >>> import sqlglot
1323            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1324            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1325
1326        Args:
1327            expressions: the SQL code strings.
1328                If `Expression` instance are passed, they will be used as-is.
1329            distinct: set the DISTINCT flag if and only if this is true.
1330            dialect: the dialect used to parse the input expression.
1331            opts: other options to use to parse the input expressions.
1332
1333        Returns:
1334            The new Except expression.
1335        """
1336        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1048    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1049        """
1050        Returns a `Subquery` that wraps around this query.
1051
1052        Example:
1053            >>> subquery = Select().select("x").from_("tbl").subquery()
1054            >>> Select().select("x").from_(subquery).sql()
1055            'SELECT x FROM (SELECT x FROM tbl)'
1056
1057        Args:
1058            alias: an optional alias for the subquery.
1059            copy: if `False`, modify this expression instance in-place.
1060        """
1061        instance = maybe_copy(self, copy)
1062        if not isinstance(alias, Expression):
1063            alias = TableAlias(this=to_identifier(alias)) if alias else None
1064
1065        return Subquery(this=instance, alias=alias)

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1067    def limit(
1068        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1069    ) -> Q:
1070        """
1071        Adds a LIMIT clause to this query.
1072
1073        Example:
1074            >>> select("1").union(select("1")).limit(1).sql()
1075            'SELECT 1 UNION SELECT 1 LIMIT 1'
1076
1077        Args:
1078            expression: the SQL code string to parse.
1079                This can also be an integer.
1080                If a `Limit` instance is passed, it will be used as-is.
1081                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1082            dialect: the dialect used to parse the input expression.
1083            copy: if `False`, modify this expression instance in-place.
1084            opts: other options to use to parse the input expressions.
1085
1086        Returns:
1087            A limited Select expression.
1088        """
1089        return _apply_builder(
1090            expression=expression,
1091            instance=self,
1092            arg="limit",
1093            into=Limit,
1094            prefix="LIMIT",
1095            dialect=dialect,
1096            copy=copy,
1097            into_arg="expression",
1098            **opts,
1099        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT 1 UNION SELECT 1 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be 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:

A limited Select expression.

def offset( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1101    def offset(
1102        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1103    ) -> Q:
1104        """
1105        Set the OFFSET expression.
1106
1107        Example:
1108            >>> Select().from_("tbl").select("x").offset(10).sql()
1109            'SELECT x FROM tbl OFFSET 10'
1110
1111        Args:
1112            expression: the SQL code string to parse.
1113                This can also be an integer.
1114                If a `Offset` instance is passed, this is used as-is.
1115                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1116            dialect: the dialect used to parse the input expression.
1117            copy: if `False`, modify this expression instance in-place.
1118            opts: other options to use to parse the input expressions.
1119
1120        Returns:
1121            The modified Select expression.
1122        """
1123        return _apply_builder(
1124            expression=expression,
1125            instance=self,
1126            arg="offset",
1127            into=Offset,
1128            prefix="OFFSET",
1129            dialect=dialect,
1130            copy=copy,
1131            into_arg="expression",
1132            **opts,
1133        )

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 order_by( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1135    def order_by(
1136        self: Q,
1137        *expressions: t.Optional[ExpOrStr],
1138        append: bool = True,
1139        dialect: DialectType = None,
1140        copy: bool = True,
1141        **opts,
1142    ) -> Q:
1143        """
1144        Set the ORDER BY expression.
1145
1146        Example:
1147            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1148            'SELECT x FROM tbl ORDER BY x DESC'
1149
1150        Args:
1151            *expressions: the SQL code strings to parse.
1152                If a `Group` instance is passed, this is used as-is.
1153                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1154            append: if `True`, add to any existing expressions.
1155                Otherwise, this flattens all the `Order` expression into a single expression.
1156            dialect: the dialect used to parse the input expression.
1157            copy: if `False`, modify this expression instance in-place.
1158            opts: other options to use to parse the input expressions.
1159
1160        Returns:
1161            The modified Select expression.
1162        """
1163        return _apply_child_list_builder(
1164            *expressions,
1165            instance=self,
1166            arg="order",
1167            append=append,
1168            copy=copy,
1169            prefix="ORDER BY",
1170            into=Order,
1171            dialect=dialect,
1172            **opts,
1173        )

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.

ctes: List[CTE]
1175    @property
1176    def ctes(self) -> t.List[CTE]:
1177        """Returns a list of all the CTEs attached to this query."""
1178        with_ = self.args.get("with")
1179        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this query.

selects: List[Expression]
1181    @property
1182    def selects(self) -> t.List[Expression]:
1183        """Returns the query's projections."""
1184        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1186    @property
1187    def named_selects(self) -> t.List[str]:
1188        """Returns the output names of the query's projections."""
1189        raise NotImplementedError("Query objects must implement `named_selects`")

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1191    def select(
1192        self: Q,
1193        *expressions: t.Optional[ExpOrStr],
1194        append: bool = True,
1195        dialect: DialectType = None,
1196        copy: bool = True,
1197        **opts,
1198    ) -> Q:
1199        """
1200        Append to or set the SELECT expressions.
1201
1202        Example:
1203            >>> Select().select("x", "y").sql()
1204            'SELECT x, y'
1205
1206        Args:
1207            *expressions: the SQL code strings to parse.
1208                If an `Expression` instance is passed, it will be used as-is.
1209            append: if `True`, add to any existing expressions.
1210                Otherwise, this resets the expressions.
1211            dialect: the dialect used to parse the input expressions.
1212            copy: if `False`, modify this expression instance in-place.
1213            opts: other options to use to parse the input expressions.
1214
1215        Returns:
1216            The modified Query expression.
1217        """
1218        raise NotImplementedError("Query objects must implement `select`")

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 Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: bool = False, **opts) -> ~Q:
1220    def with_(
1221        self: Q,
1222        alias: ExpOrStr,
1223        as_: ExpOrStr,
1224        recursive: t.Optional[bool] = None,
1225        materialized: t.Optional[bool] = None,
1226        append: bool = True,
1227        dialect: DialectType = None,
1228        copy: bool = True,
1229        scalar: bool = False,
1230        **opts,
1231    ) -> Q:
1232        """
1233        Append to or set the common table expressions.
1234
1235        Example:
1236            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1237            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1238
1239        Args:
1240            alias: the SQL code string to parse as the table name.
1241                If an `Expression` instance is passed, this is used as-is.
1242            as_: the SQL code string to parse as the table expression.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1245            materialized: set the MATERIALIZED part of the expression.
1246            append: if `True`, add to any existing expressions.
1247                Otherwise, this resets the expressions.
1248            dialect: the dialect used to parse the input expression.
1249            copy: if `False`, modify this expression instance in-place.
1250            scalar: if `True`, this is a scalar common table expression.
1251            opts: other options to use to parse the input expressions.
1252
1253        Returns:
1254            The modified expression.
1255        """
1256        return _apply_cte_builder(
1257            self,
1258            alias,
1259            as_,
1260            recursive=recursive,
1261            materialized=materialized,
1262            append=append,
1263            dialect=dialect,
1264            copy=copy,
1265            scalar=scalar,
1266            **opts,
1267        )

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.
  • materialized: set the MATERIALIZED part of the expression.
  • 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.
  • scalar: if True, this is a scalar common table expression.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Union:
1269    def union(
1270        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1271    ) -> Union:
1272        """
1273        Builds a UNION expression.
1274
1275        Example:
1276            >>> import sqlglot
1277            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1278            'SELECT * FROM foo UNION SELECT * FROM bla'
1279
1280        Args:
1281            expressions: the SQL code strings.
1282                If `Expression` instances are passed, they will be used as-is.
1283            distinct: set the DISTINCT flag if and only if this is true.
1284            dialect: the dialect used to parse the input expression.
1285            opts: other options to use to parse the input expressions.
1286
1287        Returns:
1288            The new Union expression.
1289        """
1290        return union(self, *expressions, 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:
  • expressions: the SQL code strings. If Expression instances are passed, they 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, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Intersect:
1292    def intersect(
1293        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1294    ) -> Intersect:
1295        """
1296        Builds an INTERSECT expression.
1297
1298        Example:
1299            >>> import sqlglot
1300            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1301            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1302
1303        Args:
1304            expressions: the SQL code strings.
1305                If `Expression` instances are passed, they will be used as-is.
1306            distinct: set the DISTINCT flag if and only if this is true.
1307            dialect: the dialect used to parse the input expression.
1308            opts: other options to use to parse the input expressions.
1309
1310        Returns:
1311            The new Intersect expression.
1312        """
1313        return intersect(self, *expressions, 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:
  • expressions: the SQL code strings. If Expression instances are passed, they 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, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Except:
1315    def except_(
1316        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1317    ) -> Except:
1318        """
1319        Builds an EXCEPT expression.
1320
1321        Example:
1322            >>> import sqlglot
1323            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1324            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1325
1326        Args:
1327            expressions: the SQL code strings.
1328                If `Expression` instance are passed, they will be used as-is.
1329            distinct: set the DISTINCT flag if and only if this is true.
1330            dialect: the dialect used to parse the input expression.
1331            opts: other options to use to parse the input expressions.
1332
1333        Returns:
1334            The new Except expression.
1335        """
1336        return except_(self, *expressions, 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:
  • expressions: the SQL code strings. If Expression instance are passed, they 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 = 'query'
class UDTF(DerivedTable):
1339class UDTF(DerivedTable):
1340    @property
1341    def selects(self) -> t.List[Expression]:
1342        alias = self.args.get("alias")
1343        return alias.columns if alias else []
selects: List[Expression]
1340    @property
1341    def selects(self) -> t.List[Expression]:
1342        alias = self.args.get("alias")
1343        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1346class Cache(Expression):
1347    arg_types = {
1348        "this": True,
1349        "lazy": False,
1350        "options": False,
1351        "expression": False,
1352    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1355class Uncache(Expression):
1356    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1359class Refresh(Expression):
1360    pass
key = 'refresh'
class DDL(Expression):
1363class DDL(Expression):
1364    @property
1365    def ctes(self) -> t.List[CTE]:
1366        """Returns a list of all the CTEs attached to this statement."""
1367        with_ = self.args.get("with")
1368        return with_.expressions if with_ else []
1369
1370    @property
1371    def selects(self) -> t.List[Expression]:
1372        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1373        return self.expression.selects if isinstance(self.expression, Query) else []
1374
1375    @property
1376    def named_selects(self) -> t.List[str]:
1377        """
1378        If this statement contains a query (e.g. a CTAS), this returns the output
1379        names of the query's projections.
1380        """
1381        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1364    @property
1365    def ctes(self) -> t.List[CTE]:
1366        """Returns a list of all the CTEs attached to this statement."""
1367        with_ = self.args.get("with")
1368        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this statement.

selects: List[Expression]
1370    @property
1371    def selects(self) -> t.List[Expression]:
1372        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1373        return self.expression.selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the query's projections.

named_selects: List[str]
1375    @property
1376    def named_selects(self) -> t.List[str]:
1377        """
1378        If this statement contains a query (e.g. a CTAS), this returns the output
1379        names of the query's projections.
1380        """
1381        return self.expression.named_selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the output names of the query's projections.

key = 'ddl'
class DML(Expression):
1384class DML(Expression):
1385    def returning(
1386        self,
1387        expression: ExpOrStr,
1388        dialect: DialectType = None,
1389        copy: bool = True,
1390        **opts,
1391    ) -> "Self":
1392        """
1393        Set the RETURNING expression. Not supported by all dialects.
1394
1395        Example:
1396            >>> delete("tbl").returning("*", dialect="postgres").sql()
1397            'DELETE FROM tbl RETURNING *'
1398
1399        Args:
1400            expression: the SQL code strings to parse.
1401                If an `Expression` instance is passed, it will be used as-is.
1402            dialect: the dialect used to parse the input expressions.
1403            copy: if `False`, modify this expression instance in-place.
1404            opts: other options to use to parse the input expressions.
1405
1406        Returns:
1407            Delete: the modified expression.
1408        """
1409        return _apply_builder(
1410            expression=expression,
1411            instance=self,
1412            arg="returning",
1413            prefix="RETURNING",
1414            dialect=dialect,
1415            copy=copy,
1416            into=Returning,
1417            **opts,
1418        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1385    def returning(
1386        self,
1387        expression: ExpOrStr,
1388        dialect: DialectType = None,
1389        copy: bool = True,
1390        **opts,
1391    ) -> "Self":
1392        """
1393        Set the RETURNING expression. Not supported by all dialects.
1394
1395        Example:
1396            >>> delete("tbl").returning("*", dialect="postgres").sql()
1397            'DELETE FROM tbl RETURNING *'
1398
1399        Args:
1400            expression: the SQL code strings to parse.
1401                If an `Expression` instance is passed, it will be used as-is.
1402            dialect: the dialect used to parse the input expressions.
1403            copy: if `False`, modify this expression instance in-place.
1404            opts: other options to use to parse the input expressions.
1405
1406        Returns:
1407            Delete: the modified expression.
1408        """
1409        return _apply_builder(
1410            expression=expression,
1411            instance=self,
1412            arg="returning",
1413            prefix="RETURNING",
1414            dialect=dialect,
1415            copy=copy,
1416            into=Returning,
1417            **opts,
1418        )

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):
1421class Create(DDL):
1422    arg_types = {
1423        "with": False,
1424        "this": True,
1425        "kind": True,
1426        "expression": False,
1427        "exists": False,
1428        "properties": False,
1429        "replace": False,
1430        "refresh": False,
1431        "unique": False,
1432        "indexes": False,
1433        "no_schema_binding": False,
1434        "begin": False,
1435        "end": False,
1436        "clone": False,
1437        "concurrently": False,
1438        "clustered": False,
1439    }
1440
1441    @property
1442    def kind(self) -> t.Optional[str]:
1443        kind = self.args.get("kind")
1444        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'refresh': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False, 'concurrently': False, 'clustered': False}
kind: Optional[str]
1441    @property
1442    def kind(self) -> t.Optional[str]:
1443        kind = self.args.get("kind")
1444        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1447class SequenceProperties(Expression):
1448    arg_types = {
1449        "increment": False,
1450        "minvalue": False,
1451        "maxvalue": False,
1452        "cache": False,
1453        "start": False,
1454        "owned": False,
1455        "options": False,
1456    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1459class TruncateTable(Expression):
1460    arg_types = {
1461        "expressions": True,
1462        "is_database": False,
1463        "exists": False,
1464        "only": False,
1465        "cluster": False,
1466        "identity": False,
1467        "option": False,
1468        "partition": False,
1469    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1475class Clone(Expression):
1476    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1479class Describe(Expression):
1480    arg_types = {
1481        "this": True,
1482        "style": False,
1483        "kind": False,
1484        "expressions": False,
1485        "partition": False,
1486        "format": False,
1487    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1491class Attach(Expression):
1492    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1496class Detach(Expression):
1497    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1501class Summarize(Expression):
1502    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1505class Kill(Expression):
1506    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1509class Pragma(Expression):
1510    pass
key = 'pragma'
class Declare(Expression):
1513class Declare(Expression):
1514    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1517class DeclareItem(Expression):
1518    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1521class Set(Expression):
1522    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1525class Heredoc(Expression):
1526    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1529class SetItem(Expression):
1530    arg_types = {
1531        "this": False,
1532        "expressions": False,
1533        "kind": False,
1534        "collate": False,  # MySQL SET NAMES statement
1535        "global": False,
1536    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1539class Show(Expression):
1540    arg_types = {
1541        "this": True,
1542        "history": False,
1543        "terse": False,
1544        "target": False,
1545        "offset": False,
1546        "starts_with": False,
1547        "limit": False,
1548        "from": False,
1549        "like": False,
1550        "where": False,
1551        "db": False,
1552        "scope": False,
1553        "scope_kind": False,
1554        "full": False,
1555        "mutex": False,
1556        "query": False,
1557        "channel": False,
1558        "global": False,
1559        "log": False,
1560        "position": False,
1561        "types": False,
1562        "privileges": False,
1563    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': 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, 'privileges': False}
key = 'show'
class UserDefinedFunction(Expression):
1566class UserDefinedFunction(Expression):
1567    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1570class CharacterSet(Expression):
1571    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1574class RecursiveWithSearch(Expression):
1575    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key = 'recursivewithsearch'
class With(Expression):
1578class With(Expression):
1579    arg_types = {"expressions": True, "recursive": False, "search": False}
1580
1581    @property
1582    def recursive(self) -> bool:
1583        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1581    @property
1582    def recursive(self) -> bool:
1583        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1586class WithinGroup(Expression):
1587    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1592class CTE(DerivedTable):
1593    arg_types = {
1594        "this": True,
1595        "alias": True,
1596        "scalar": False,
1597        "materialized": False,
1598    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1601class ProjectionDef(Expression):
1602    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1605class TableAlias(Expression):
1606    arg_types = {"this": False, "columns": False}
1607
1608    @property
1609    def columns(self):
1610        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1608    @property
1609    def columns(self):
1610        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1613class BitString(Condition):
1614    pass
key = 'bitstring'
class HexString(Condition):
1617class HexString(Condition):
1618    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1621class ByteString(Condition):
1622    pass
key = 'bytestring'
class RawString(Condition):
1625class RawString(Condition):
1626    pass
key = 'rawstring'
class UnicodeString(Condition):
1629class UnicodeString(Condition):
1630    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1633class Column(Condition):
1634    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1635
1636    @property
1637    def table(self) -> str:
1638        return self.text("table")
1639
1640    @property
1641    def db(self) -> str:
1642        return self.text("db")
1643
1644    @property
1645    def catalog(self) -> str:
1646        return self.text("catalog")
1647
1648    @property
1649    def output_name(self) -> str:
1650        return self.name
1651
1652    @property
1653    def parts(self) -> t.List[Identifier]:
1654        """Return the parts of a column in order catalog, db, table, name."""
1655        return [
1656            t.cast(Identifier, self.args[part])
1657            for part in ("catalog", "db", "table", "this")
1658            if self.args.get(part)
1659        ]
1660
1661    def to_dot(self) -> Dot | Identifier:
1662        """Converts the column into a dot expression."""
1663        parts = self.parts
1664        parent = self.parent
1665
1666        while parent:
1667            if isinstance(parent, Dot):
1668                parts.append(parent.expression)
1669            parent = parent.parent
1670
1671        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
1636    @property
1637    def table(self) -> str:
1638        return self.text("table")
db: str
1640    @property
1641    def db(self) -> str:
1642        return self.text("db")
catalog: str
1644    @property
1645    def catalog(self) -> str:
1646        return self.text("catalog")
output_name: str
1648    @property
1649    def output_name(self) -> str:
1650        return self.name

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]
1652    @property
1653    def parts(self) -> t.List[Identifier]:
1654        """Return the parts of a column in order catalog, db, table, name."""
1655        return [
1656            t.cast(Identifier, self.args[part])
1657            for part in ("catalog", "db", "table", "this")
1658            if self.args.get(part)
1659        ]

Return the parts of a column in order catalog, db, table, name.

def to_dot(self) -> Dot | Identifier:
1661    def to_dot(self) -> Dot | Identifier:
1662        """Converts the column into a dot expression."""
1663        parts = self.parts
1664        parent = self.parent
1665
1666        while parent:
1667            if isinstance(parent, Dot):
1668                parts.append(parent.expression)
1669            parent = parent.parent
1670
1671        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1674class ColumnPosition(Expression):
1675    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1678class ColumnDef(Expression):
1679    arg_types = {
1680        "this": True,
1681        "kind": False,
1682        "constraints": False,
1683        "exists": False,
1684        "position": False,
1685        "default": False,
1686        "output": False,
1687    }
1688
1689    @property
1690    def constraints(self) -> t.List[ColumnConstraint]:
1691        return self.args.get("constraints") or []
1692
1693    @property
1694    def kind(self) -> t.Optional[DataType]:
1695        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1689    @property
1690    def constraints(self) -> t.List[ColumnConstraint]:
1691        return self.args.get("constraints") or []
kind: Optional[DataType]
1693    @property
1694    def kind(self) -> t.Optional[DataType]:
1695        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1698class AlterColumn(Expression):
1699    arg_types = {
1700        "this": True,
1701        "dtype": False,
1702        "collate": False,
1703        "using": False,
1704        "default": False,
1705        "drop": False,
1706        "comment": False,
1707        "allow_null": False,
1708        "visible": False,
1709    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False}
key = 'altercolumn'
class AlterIndex(Expression):
1713class AlterIndex(Expression):
1714    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1718class AlterDistStyle(Expression):
1719    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1722class AlterSortKey(Expression):
1723    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1726class AlterSet(Expression):
1727    arg_types = {
1728        "expressions": False,
1729        "option": False,
1730        "tablespace": False,
1731        "access_method": False,
1732        "file_format": False,
1733        "copy_options": False,
1734        "tag": False,
1735        "location": False,
1736        "serde": False,
1737    }
arg_types = {'expressions': False, 'option': False, 'tablespace': False, 'access_method': False, 'file_format': False, 'copy_options': False, 'tag': False, 'location': False, 'serde': False}
key = 'alterset'
class RenameColumn(Expression):
1740class RenameColumn(Expression):
1741    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1744class AlterRename(Expression):
1745    pass
key = 'alterrename'
class SwapTable(Expression):
1748class SwapTable(Expression):
1749    pass
key = 'swaptable'
class Comment(Expression):
1752class Comment(Expression):
1753    arg_types = {
1754        "this": True,
1755        "kind": True,
1756        "expression": True,
1757        "exists": False,
1758        "materialized": False,
1759    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1762class Comprehension(Expression):
1763    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):
1767class MergeTreeTTLAction(Expression):
1768    arg_types = {
1769        "this": True,
1770        "delete": False,
1771        "recompress": False,
1772        "to_disk": False,
1773        "to_volume": False,
1774    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1778class MergeTreeTTL(Expression):
1779    arg_types = {
1780        "expressions": True,
1781        "where": False,
1782        "group": False,
1783        "aggregates": False,
1784    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1788class IndexConstraintOption(Expression):
1789    arg_types = {
1790        "key_block_size": False,
1791        "using": False,
1792        "parser": False,
1793        "comment": False,
1794        "visible": False,
1795        "engine_attr": False,
1796        "secondary_engine_attr": False,
1797    }
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):
1800class ColumnConstraint(Expression):
1801    arg_types = {"this": False, "kind": True}
1802
1803    @property
1804    def kind(self) -> ColumnConstraintKind:
1805        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1803    @property
1804    def kind(self) -> ColumnConstraintKind:
1805        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1808class ColumnConstraintKind(Expression):
1809    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1812class AutoIncrementColumnConstraint(ColumnConstraintKind):
1813    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1816class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1817    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1820class CaseSpecificColumnConstraint(ColumnConstraintKind):
1821    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1824class CharacterSetColumnConstraint(ColumnConstraintKind):
1825    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1828class CheckColumnConstraint(ColumnConstraintKind):
1829    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1832class ClusteredColumnConstraint(ColumnConstraintKind):
1833    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1836class CollateColumnConstraint(ColumnConstraintKind):
1837    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1840class CommentColumnConstraint(ColumnConstraintKind):
1841    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1844class CompressColumnConstraint(ColumnConstraintKind):
1845    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1848class DateFormatColumnConstraint(ColumnConstraintKind):
1849    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1852class DefaultColumnConstraint(ColumnConstraintKind):
1853    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1856class EncodeColumnConstraint(ColumnConstraintKind):
1857    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1861class ExcludeColumnConstraint(ColumnConstraintKind):
1862    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1865class EphemeralColumnConstraint(ColumnConstraintKind):
1866    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1869class WithOperator(Expression):
1870    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1873class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1874    # this: True -> ALWAYS, this: False -> BY DEFAULT
1875    arg_types = {
1876        "this": False,
1877        "expression": False,
1878        "on_null": False,
1879        "start": False,
1880        "increment": False,
1881        "minvalue": False,
1882        "maxvalue": False,
1883        "cycle": False,
1884    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1887class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1888    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1893class IndexColumnConstraint(ColumnConstraintKind):
1894    arg_types = {
1895        "this": False,
1896        "expressions": False,
1897        "kind": False,
1898        "index_type": False,
1899        "options": False,
1900        "expression": False,  # Clickhouse
1901        "granularity": False,
1902    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1905class InlineLengthColumnConstraint(ColumnConstraintKind):
1906    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1909class NonClusteredColumnConstraint(ColumnConstraintKind):
1910    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1913class NotForReplicationColumnConstraint(ColumnConstraintKind):
1914    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1918class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1919    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1922class NotNullColumnConstraint(ColumnConstraintKind):
1923    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1927class OnUpdateColumnConstraint(ColumnConstraintKind):
1928    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1932class TransformColumnConstraint(ColumnConstraintKind):
1933    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1936class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1937    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1940class TitleColumnConstraint(ColumnConstraintKind):
1941    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1944class UniqueColumnConstraint(ColumnConstraintKind):
1945    arg_types = {
1946        "this": False,
1947        "index_type": False,
1948        "on_conflict": False,
1949        "nulls": False,
1950        "options": False,
1951    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1954class UppercaseColumnConstraint(ColumnConstraintKind):
1955    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1959class WatermarkColumnConstraint(Expression):
1960    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1963class PathColumnConstraint(ColumnConstraintKind):
1964    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1968class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1969    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1974class ComputedColumnConstraint(ColumnConstraintKind):
1975    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1978class Constraint(Expression):
1979    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1982class Delete(DML):
1983    arg_types = {
1984        "with": False,
1985        "this": False,
1986        "using": False,
1987        "where": False,
1988        "returning": False,
1989        "limit": False,
1990        "tables": False,  # Multiple-Table Syntax (MySQL)
1991        "cluster": False,  # Clickhouse
1992    }
1993
1994    def delete(
1995        self,
1996        table: ExpOrStr,
1997        dialect: DialectType = None,
1998        copy: bool = True,
1999        **opts,
2000    ) -> Delete:
2001        """
2002        Create a DELETE expression or replace the table on an existing DELETE expression.
2003
2004        Example:
2005            >>> delete("tbl").sql()
2006            'DELETE FROM tbl'
2007
2008        Args:
2009            table: the table from which to delete.
2010            dialect: the dialect used to parse the input expression.
2011            copy: if `False`, modify this expression instance in-place.
2012            opts: other options to use to parse the input expressions.
2013
2014        Returns:
2015            Delete: the modified expression.
2016        """
2017        return _apply_builder(
2018            expression=table,
2019            instance=self,
2020            arg="this",
2021            dialect=dialect,
2022            into=Table,
2023            copy=copy,
2024            **opts,
2025        )
2026
2027    def where(
2028        self,
2029        *expressions: t.Optional[ExpOrStr],
2030        append: bool = True,
2031        dialect: DialectType = None,
2032        copy: bool = True,
2033        **opts,
2034    ) -> Delete:
2035        """
2036        Append to or set the WHERE expressions.
2037
2038        Example:
2039            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2040            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2041
2042        Args:
2043            *expressions: the SQL code strings to parse.
2044                If an `Expression` instance is passed, it will be used as-is.
2045                Multiple expressions are combined with an AND operator.
2046            append: if `True`, AND the new expressions to any existing expression.
2047                Otherwise, this resets the expression.
2048            dialect: the dialect used to parse the input expressions.
2049            copy: if `False`, modify this expression instance in-place.
2050            opts: other options to use to parse the input expressions.
2051
2052        Returns:
2053            Delete: the modified expression.
2054        """
2055        return _apply_conjunction_builder(
2056            *expressions,
2057            instance=self,
2058            arg="where",
2059            append=append,
2060            into=Where,
2061            dialect=dialect,
2062            copy=copy,
2063            **opts,
2064        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1994    def delete(
1995        self,
1996        table: ExpOrStr,
1997        dialect: DialectType = None,
1998        copy: bool = True,
1999        **opts,
2000    ) -> Delete:
2001        """
2002        Create a DELETE expression or replace the table on an existing DELETE expression.
2003
2004        Example:
2005            >>> delete("tbl").sql()
2006            'DELETE FROM tbl'
2007
2008        Args:
2009            table: the table from which to delete.
2010            dialect: the dialect used to parse the input expression.
2011            copy: if `False`, modify this expression instance in-place.
2012            opts: other options to use to parse the input expressions.
2013
2014        Returns:
2015            Delete: the modified expression.
2016        """
2017        return _apply_builder(
2018            expression=table,
2019            instance=self,
2020            arg="this",
2021            dialect=dialect,
2022            into=Table,
2023            copy=copy,
2024            **opts,
2025        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2027    def where(
2028        self,
2029        *expressions: t.Optional[ExpOrStr],
2030        append: bool = True,
2031        dialect: DialectType = None,
2032        copy: bool = True,
2033        **opts,
2034    ) -> Delete:
2035        """
2036        Append to or set the WHERE expressions.
2037
2038        Example:
2039            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2040            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2041
2042        Args:
2043            *expressions: the SQL code strings to parse.
2044                If an `Expression` instance is passed, it will be used as-is.
2045                Multiple expressions are combined with an AND operator.
2046            append: if `True`, AND the new expressions to any existing expression.
2047                Otherwise, this resets the expression.
2048            dialect: the dialect used to parse the input expressions.
2049            copy: if `False`, modify this expression instance in-place.
2050            opts: other options to use to parse the input expressions.
2051
2052        Returns:
2053            Delete: the modified expression.
2054        """
2055        return _apply_conjunction_builder(
2056            *expressions,
2057            instance=self,
2058            arg="where",
2059            append=append,
2060            into=Where,
2061            dialect=dialect,
2062            copy=copy,
2063            **opts,
2064        )

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):
2067class Drop(Expression):
2068    arg_types = {
2069        "this": False,
2070        "kind": False,
2071        "expressions": False,
2072        "exists": False,
2073        "temporary": False,
2074        "materialized": False,
2075        "cascade": False,
2076        "constraints": False,
2077        "purge": False,
2078        "cluster": False,
2079        "concurrently": False,
2080    }
2081
2082    @property
2083    def kind(self) -> t.Optional[str]:
2084        kind = self.args.get("kind")
2085        return kind and kind.upper()
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False, 'concurrently': False}
kind: Optional[str]
2082    @property
2083    def kind(self) -> t.Optional[str]:
2084        kind = self.args.get("kind")
2085        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2089class Export(Expression):
2090    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2093class Filter(Expression):
2094    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2097class Check(Expression):
2098    pass
key = 'check'
class Changes(Expression):
2101class Changes(Expression):
2102    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2106class Connect(Expression):
2107    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2110class CopyParameter(Expression):
2111    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2114class Copy(DML):
2115    arg_types = {
2116        "this": True,
2117        "kind": True,
2118        "files": True,
2119        "credentials": False,
2120        "format": False,
2121        "params": False,
2122    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2125class Credentials(Expression):
2126    arg_types = {
2127        "credentials": False,
2128        "encryption": False,
2129        "storage": False,
2130        "iam_role": False,
2131        "region": False,
2132    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2135class Prior(Expression):
2136    pass
key = 'prior'
class Directory(Expression):
2139class Directory(Expression):
2140    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2141    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2144class ForeignKey(Expression):
2145    arg_types = {
2146        "expressions": False,
2147        "reference": False,
2148        "delete": False,
2149        "update": False,
2150        "options": False,
2151    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2154class ColumnPrefix(Expression):
2155    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2158class PrimaryKey(Expression):
2159    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2164class Into(Expression):
2165    arg_types = {
2166        "this": False,
2167        "temporary": False,
2168        "unlogged": False,
2169        "bulk_collect": False,
2170        "expressions": False,
2171    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2174class From(Expression):
2175    @property
2176    def name(self) -> str:
2177        return self.this.name
2178
2179    @property
2180    def alias_or_name(self) -> str:
2181        return self.this.alias_or_name
name: str
2175    @property
2176    def name(self) -> str:
2177        return self.this.name
alias_or_name: str
2179    @property
2180    def alias_or_name(self) -> str:
2181        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2184class Having(Expression):
2185    pass
key = 'having'
class Hint(Expression):
2188class Hint(Expression):
2189    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2192class JoinHint(Expression):
2193    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2196class Identifier(Expression):
2197    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2198
2199    @property
2200    def quoted(self) -> bool:
2201        return bool(self.args.get("quoted"))
2202
2203    @property
2204    def hashable_args(self) -> t.Any:
2205        return (self.this, self.quoted)
2206
2207    @property
2208    def output_name(self) -> str:
2209        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2199    @property
2200    def quoted(self) -> bool:
2201        return bool(self.args.get("quoted"))
hashable_args: Any
2203    @property
2204    def hashable_args(self) -> t.Any:
2205        return (self.this, self.quoted)
output_name: str
2207    @property
2208    def output_name(self) -> str:
2209        return self.name

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):
2213class Opclass(Expression):
2214    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2217class Index(Expression):
2218    arg_types = {
2219        "this": False,
2220        "table": False,
2221        "unique": False,
2222        "primary": False,
2223        "amp": False,  # teradata
2224        "params": False,
2225    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2228class IndexParameters(Expression):
2229    arg_types = {
2230        "using": False,
2231        "include": False,
2232        "columns": False,
2233        "with_storage": False,
2234        "partition_by": False,
2235        "tablespace": False,
2236        "where": False,
2237        "on": False,
2238    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
class Insert(DDL, DML):
2241class Insert(DDL, DML):
2242    arg_types = {
2243        "hint": False,
2244        "with": False,
2245        "is_function": False,
2246        "this": False,
2247        "expression": False,
2248        "conflict": False,
2249        "returning": False,
2250        "overwrite": False,
2251        "exists": False,
2252        "alternative": False,
2253        "where": False,
2254        "ignore": False,
2255        "by_name": False,
2256        "stored": False,
2257        "partition": False,
2258        "settings": False,
2259        "source": False,
2260    }
2261
2262    def with_(
2263        self,
2264        alias: ExpOrStr,
2265        as_: ExpOrStr,
2266        recursive: t.Optional[bool] = None,
2267        materialized: t.Optional[bool] = None,
2268        append: bool = True,
2269        dialect: DialectType = None,
2270        copy: bool = True,
2271        **opts,
2272    ) -> Insert:
2273        """
2274        Append to or set the common table expressions.
2275
2276        Example:
2277            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2278            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2279
2280        Args:
2281            alias: the SQL code string to parse as the table name.
2282                If an `Expression` instance is passed, this is used as-is.
2283            as_: the SQL code string to parse as the table expression.
2284                If an `Expression` instance is passed, it will be used as-is.
2285            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2286            materialized: set the MATERIALIZED part of the expression.
2287            append: if `True`, add to any existing expressions.
2288                Otherwise, this resets the expressions.
2289            dialect: the dialect used to parse the input expression.
2290            copy: if `False`, modify this expression instance in-place.
2291            opts: other options to use to parse the input expressions.
2292
2293        Returns:
2294            The modified expression.
2295        """
2296        return _apply_cte_builder(
2297            self,
2298            alias,
2299            as_,
2300            recursive=recursive,
2301            materialized=materialized,
2302            append=append,
2303            dialect=dialect,
2304            copy=copy,
2305            **opts,
2306        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2262    def with_(
2263        self,
2264        alias: ExpOrStr,
2265        as_: ExpOrStr,
2266        recursive: t.Optional[bool] = None,
2267        materialized: t.Optional[bool] = None,
2268        append: bool = True,
2269        dialect: DialectType = None,
2270        copy: bool = True,
2271        **opts,
2272    ) -> Insert:
2273        """
2274        Append to or set the common table expressions.
2275
2276        Example:
2277            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2278            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2279
2280        Args:
2281            alias: the SQL code string to parse as the table name.
2282                If an `Expression` instance is passed, this is used as-is.
2283            as_: the SQL code string to parse as the table expression.
2284                If an `Expression` instance is passed, it will be used as-is.
2285            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2286            materialized: set the MATERIALIZED part of the expression.
2287            append: if `True`, add to any existing expressions.
2288                Otherwise, this resets the expressions.
2289            dialect: the dialect used to parse the input expression.
2290            copy: if `False`, modify this expression instance in-place.
2291            opts: other options to use to parse the input expressions.
2292
2293        Returns:
2294            The modified expression.
2295        """
2296        return _apply_cte_builder(
2297            self,
2298            alias,
2299            as_,
2300            recursive=recursive,
2301            materialized=materialized,
2302            append=append,
2303            dialect=dialect,
2304            copy=copy,
2305            **opts,
2306        )

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.
  • materialized: set the MATERIALIZED part of the expression.
  • 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 ConditionalInsert(Expression):
2309class ConditionalInsert(Expression):
2310    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2313class MultitableInserts(Expression):
2314    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2317class OnConflict(Expression):
2318    arg_types = {
2319        "duplicate": False,
2320        "expressions": False,
2321        "action": False,
2322        "conflict_keys": False,
2323        "constraint": False,
2324        "where": False,
2325    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2328class OnCondition(Expression):
2329    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2332class Returning(Expression):
2333    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2337class Introducer(Expression):
2338    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2342class National(Expression):
2343    pass
key = 'national'
class LoadData(Expression):
2346class LoadData(Expression):
2347    arg_types = {
2348        "this": True,
2349        "local": False,
2350        "overwrite": False,
2351        "inpath": True,
2352        "partition": False,
2353        "input_format": False,
2354        "serde": False,
2355    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2358class Partition(Expression):
2359    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2362class PartitionRange(Expression):
2363    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2367class PartitionId(Expression):
2368    pass
key = 'partitionid'
class Fetch(Expression):
2371class Fetch(Expression):
2372    arg_types = {
2373        "direction": False,
2374        "count": False,
2375        "limit_options": False,
2376    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2379class Grant(Expression):
2380    arg_types = {
2381        "privileges": True,
2382        "kind": False,
2383        "securable": True,
2384        "principals": True,
2385        "grant_option": False,
2386    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2389class Group(Expression):
2390    arg_types = {
2391        "expressions": False,
2392        "grouping_sets": False,
2393        "cube": False,
2394        "rollup": False,
2395        "totals": False,
2396        "all": False,
2397    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2400class Cube(Expression):
2401    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2404class Rollup(Expression):
2405    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2408class GroupingSets(Expression):
2409    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2412class Lambda(Expression):
2413    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2416class Limit(Expression):
2417    arg_types = {
2418        "this": False,
2419        "expression": True,
2420        "offset": False,
2421        "limit_options": False,
2422        "expressions": False,
2423    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2426class LimitOptions(Expression):
2427    arg_types = {
2428        "percent": False,
2429        "rows": False,
2430        "with_ties": False,
2431    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2434class Literal(Condition):
2435    arg_types = {"this": True, "is_string": True}
2436
2437    @property
2438    def hashable_args(self) -> t.Any:
2439        return (self.this, self.args.get("is_string"))
2440
2441    @classmethod
2442    def number(cls, number) -> Literal:
2443        return cls(this=str(number), is_string=False)
2444
2445    @classmethod
2446    def string(cls, string) -> Literal:
2447        return cls(this=str(string), is_string=True)
2448
2449    @property
2450    def output_name(self) -> str:
2451        return self.name
2452
2453    def to_py(self) -> int | str | Decimal:
2454        if self.is_number:
2455            try:
2456                return int(self.this)
2457            except ValueError:
2458                return Decimal(self.this)
2459        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2437    @property
2438    def hashable_args(self) -> t.Any:
2439        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2441    @classmethod
2442    def number(cls, number) -> Literal:
2443        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2445    @classmethod
2446    def string(cls, string) -> Literal:
2447        return cls(this=str(string), is_string=True)
output_name: str
2449    @property
2450    def output_name(self) -> str:
2451        return self.name

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 to_py(self) -> int | str | decimal.Decimal:
2453    def to_py(self) -> int | str | Decimal:
2454        if self.is_number:
2455            try:
2456                return int(self.this)
2457            except ValueError:
2458                return Decimal(self.this)
2459        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2462class Join(Expression):
2463    arg_types = {
2464        "this": True,
2465        "on": False,
2466        "side": False,
2467        "kind": False,
2468        "using": False,
2469        "method": False,
2470        "global": False,
2471        "hint": False,
2472        "match_condition": False,  # Snowflake
2473        "expressions": False,
2474    }
2475
2476    @property
2477    def method(self) -> str:
2478        return self.text("method").upper()
2479
2480    @property
2481    def kind(self) -> str:
2482        return self.text("kind").upper()
2483
2484    @property
2485    def side(self) -> str:
2486        return self.text("side").upper()
2487
2488    @property
2489    def hint(self) -> str:
2490        return self.text("hint").upper()
2491
2492    @property
2493    def alias_or_name(self) -> str:
2494        return self.this.alias_or_name
2495
2496    @property
2497    def is_semi_or_anti_join(self) -> bool:
2498        return self.kind in ("SEMI", "ANTI")
2499
2500    def on(
2501        self,
2502        *expressions: t.Optional[ExpOrStr],
2503        append: bool = True,
2504        dialect: DialectType = None,
2505        copy: bool = True,
2506        **opts,
2507    ) -> Join:
2508        """
2509        Append to or set the ON expressions.
2510
2511        Example:
2512            >>> import sqlglot
2513            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2514            'JOIN x ON y = 1'
2515
2516        Args:
2517            *expressions: the SQL code strings to parse.
2518                If an `Expression` instance is passed, it will be used as-is.
2519                Multiple expressions are combined with an AND operator.
2520            append: if `True`, AND the new expressions to any existing expression.
2521                Otherwise, this resets the expression.
2522            dialect: the dialect used to parse the input expressions.
2523            copy: if `False`, modify this expression instance in-place.
2524            opts: other options to use to parse the input expressions.
2525
2526        Returns:
2527            The modified Join expression.
2528        """
2529        join = _apply_conjunction_builder(
2530            *expressions,
2531            instance=self,
2532            arg="on",
2533            append=append,
2534            dialect=dialect,
2535            copy=copy,
2536            **opts,
2537        )
2538
2539        if join.kind == "CROSS":
2540            join.set("kind", None)
2541
2542        return join
2543
2544    def using(
2545        self,
2546        *expressions: t.Optional[ExpOrStr],
2547        append: bool = True,
2548        dialect: DialectType = None,
2549        copy: bool = True,
2550        **opts,
2551    ) -> Join:
2552        """
2553        Append to or set the USING expressions.
2554
2555        Example:
2556            >>> import sqlglot
2557            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2558            'JOIN x USING (foo, bla)'
2559
2560        Args:
2561            *expressions: the SQL code strings to parse.
2562                If an `Expression` instance is passed, it will be used as-is.
2563            append: if `True`, concatenate the new expressions to the existing "using" list.
2564                Otherwise, this resets the expression.
2565            dialect: the dialect used to parse the input expressions.
2566            copy: if `False`, modify this expression instance in-place.
2567            opts: other options to use to parse the input expressions.
2568
2569        Returns:
2570            The modified Join expression.
2571        """
2572        join = _apply_list_builder(
2573            *expressions,
2574            instance=self,
2575            arg="using",
2576            append=append,
2577            dialect=dialect,
2578            copy=copy,
2579            **opts,
2580        )
2581
2582        if join.kind == "CROSS":
2583            join.set("kind", None)
2584
2585        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False}
method: str
2476    @property
2477    def method(self) -> str:
2478        return self.text("method").upper()
kind: str
2480    @property
2481    def kind(self) -> str:
2482        return self.text("kind").upper()
side: str
2484    @property
2485    def side(self) -> str:
2486        return self.text("side").upper()
hint: str
2488    @property
2489    def hint(self) -> str:
2490        return self.text("hint").upper()
alias_or_name: str
2492    @property
2493    def alias_or_name(self) -> str:
2494        return self.this.alias_or_name
is_semi_or_anti_join: bool
2496    @property
2497    def is_semi_or_anti_join(self) -> bool:
2498        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2500    def on(
2501        self,
2502        *expressions: t.Optional[ExpOrStr],
2503        append: bool = True,
2504        dialect: DialectType = None,
2505        copy: bool = True,
2506        **opts,
2507    ) -> Join:
2508        """
2509        Append to or set the ON expressions.
2510
2511        Example:
2512            >>> import sqlglot
2513            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2514            'JOIN x ON y = 1'
2515
2516        Args:
2517            *expressions: the SQL code strings to parse.
2518                If an `Expression` instance is passed, it will be used as-is.
2519                Multiple expressions are combined with an AND operator.
2520            append: if `True`, AND the new expressions to any existing expression.
2521                Otherwise, this resets the expression.
2522            dialect: the dialect used to parse the input expressions.
2523            copy: if `False`, modify this expression instance in-place.
2524            opts: other options to use to parse the input expressions.
2525
2526        Returns:
2527            The modified Join expression.
2528        """
2529        join = _apply_conjunction_builder(
2530            *expressions,
2531            instance=self,
2532            arg="on",
2533            append=append,
2534            dialect=dialect,
2535            copy=copy,
2536            **opts,
2537        )
2538
2539        if join.kind == "CROSS":
2540            join.set("kind", None)
2541
2542        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2544    def using(
2545        self,
2546        *expressions: t.Optional[ExpOrStr],
2547        append: bool = True,
2548        dialect: DialectType = None,
2549        copy: bool = True,
2550        **opts,
2551    ) -> Join:
2552        """
2553        Append to or set the USING expressions.
2554
2555        Example:
2556            >>> import sqlglot
2557            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2558            'JOIN x USING (foo, bla)'
2559
2560        Args:
2561            *expressions: the SQL code strings to parse.
2562                If an `Expression` instance is passed, it will be used as-is.
2563            append: if `True`, concatenate the new expressions to the existing "using" list.
2564                Otherwise, this resets the expression.
2565            dialect: the dialect used to parse the input expressions.
2566            copy: if `False`, modify this expression instance in-place.
2567            opts: other options to use to parse the input expressions.
2568
2569        Returns:
2570            The modified Join expression.
2571        """
2572        join = _apply_list_builder(
2573            *expressions,
2574            instance=self,
2575            arg="using",
2576            append=append,
2577            dialect=dialect,
2578            copy=copy,
2579            **opts,
2580        )
2581
2582        if join.kind == "CROSS":
2583            join.set("kind", None)
2584
2585        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):
2588class Lateral(UDTF):
2589    arg_types = {
2590        "this": True,
2591        "view": False,
2592        "outer": False,
2593        "alias": False,
2594        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2595        "ordinality": False,
2596    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2601class TableFromRows(UDTF):
2602    arg_types = {
2603        "this": True,
2604        "alias": False,
2605        "joins": False,
2606        "pivots": False,
2607        "sample": False,
2608    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2611class MatchRecognizeMeasure(Expression):
2612    arg_types = {
2613        "this": True,
2614        "window_frame": False,
2615    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2618class MatchRecognize(Expression):
2619    arg_types = {
2620        "partition_by": False,
2621        "order": False,
2622        "measures": False,
2623        "rows": False,
2624        "after": False,
2625        "pattern": False,
2626        "define": False,
2627        "alias": False,
2628    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2633class Final(Expression):
2634    pass
key = 'final'
class Offset(Expression):
2637class Offset(Expression):
2638    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2641class Order(Expression):
2642    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2646class WithFill(Expression):
2647    arg_types = {
2648        "from": False,
2649        "to": False,
2650        "step": False,
2651        "interpolate": False,
2652    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2657class Cluster(Order):
2658    pass
key = 'cluster'
class Distribute(Order):
2661class Distribute(Order):
2662    pass
key = 'distribute'
class Sort(Order):
2665class Sort(Order):
2666    pass
key = 'sort'
class Ordered(Expression):
2669class Ordered(Expression):
2670    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2671
2672    @property
2673    def name(self) -> str:
2674        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2672    @property
2673    def name(self) -> str:
2674        return self.this.name
key = 'ordered'
class Property(Expression):
2677class Property(Expression):
2678    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2681class GrantPrivilege(Expression):
2682    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2685class GrantPrincipal(Expression):
2686    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2689class AllowedValuesProperty(Expression):
2690    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2693class AlgorithmProperty(Property):
2694    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2697class AutoIncrementProperty(Property):
2698    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2702class AutoRefreshProperty(Property):
2703    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2706class BackupProperty(Property):
2707    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2710class BlockCompressionProperty(Property):
2711    arg_types = {
2712        "autotemp": False,
2713        "always": False,
2714        "default": False,
2715        "manual": False,
2716        "never": False,
2717    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2720class CharacterSetProperty(Property):
2721    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2724class ChecksumProperty(Property):
2725    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2728class CollateProperty(Property):
2729    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2732class CopyGrantsProperty(Property):
2733    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2736class DataBlocksizeProperty(Property):
2737    arg_types = {
2738        "size": False,
2739        "units": False,
2740        "minimum": False,
2741        "maximum": False,
2742        "default": False,
2743    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2746class DataDeletionProperty(Property):
2747    arg_types = {"on": True, "filter_col": False, "retention_period": False}
arg_types = {'on': True, 'filter_col': False, 'retention_period': False}
key = 'datadeletionproperty'
class DefinerProperty(Property):
2750class DefinerProperty(Property):
2751    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2754class DistKeyProperty(Property):
2755    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2760class DistributedByProperty(Property):
2761    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
arg_types = {'expressions': False, 'kind': True, 'buckets': False, 'order': False}
key = 'distributedbyproperty'
class DistStyleProperty(Property):
2764class DistStyleProperty(Property):
2765    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2768class DuplicateKeyProperty(Property):
2769    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2772class EngineProperty(Property):
2773    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2776class HeapProperty(Property):
2777    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2780class ToTableProperty(Property):
2781    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2784class ExecuteAsProperty(Property):
2785    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2788class ExternalProperty(Property):
2789    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2792class FallbackProperty(Property):
2793    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2796class FileFormatProperty(Property):
2797    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2800class CredentialsProperty(Property):
2801    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2804class FreespaceProperty(Property):
2805    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2808class GlobalProperty(Property):
2809    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2812class IcebergProperty(Property):
2813    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2816class InheritsProperty(Property):
2817    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2820class InputModelProperty(Property):
2821    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2824class OutputModelProperty(Property):
2825    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2828class IsolatedLoadingProperty(Property):
2829    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2832class JournalProperty(Property):
2833    arg_types = {
2834        "no": False,
2835        "dual": False,
2836        "before": False,
2837        "local": False,
2838        "after": False,
2839    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2842class LanguageProperty(Property):
2843    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2847class ClusteredByProperty(Property):
2848    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2851class DictProperty(Property):
2852    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2855class DictSubProperty(Property):
2856    pass
key = 'dictsubproperty'
class DictRange(Property):
2859class DictRange(Property):
2860    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2863class DynamicProperty(Property):
2864    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2869class OnCluster(Property):
2870    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2874class EmptyProperty(Property):
2875    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2878class LikeProperty(Property):
2879    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2882class LocationProperty(Property):
2883    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2886class LockProperty(Property):
2887    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2890class LockingProperty(Property):
2891    arg_types = {
2892        "this": False,
2893        "kind": True,
2894        "for_or_in": False,
2895        "lock_type": True,
2896        "override": False,
2897    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2900class LogProperty(Property):
2901    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2904class MaterializedProperty(Property):
2905    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2908class MergeBlockRatioProperty(Property):
2909    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):
2912class NoPrimaryIndexProperty(Property):
2913    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2916class OnProperty(Property):
2917    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2920class OnCommitProperty(Property):
2921    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2924class PartitionedByProperty(Property):
2925    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
2928class PartitionedByBucket(Property):
2929    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
2932class PartitionByTruncate(Property):
2933    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
2937class PartitionByRangeProperty(Property):
2938    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2942class PartitionByRangePropertyDynamic(Expression):
2943    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class UniqueKeyProperty(Property):
2947class UniqueKeyProperty(Property):
2948    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2952class PartitionBoundSpec(Expression):
2953    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2954    arg_types = {
2955        "this": False,
2956        "expression": False,
2957        "from_expressions": False,
2958        "to_expressions": False,
2959    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2962class PartitionedOfProperty(Property):
2963    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2964    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2967class StreamingTableProperty(Property):
2968    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2971class RemoteWithConnectionModelProperty(Property):
2972    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2975class ReturnsProperty(Property):
2976    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
arg_types = {'this': False, 'is_table': False, 'table': False, 'null': False}
key = 'returnsproperty'
class StrictProperty(Property):
2979class StrictProperty(Property):
2980    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2983class RowFormatProperty(Property):
2984    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2987class RowFormatDelimitedProperty(Property):
2988    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2989    arg_types = {
2990        "fields": False,
2991        "escaped": False,
2992        "collection_items": False,
2993        "map_keys": False,
2994        "lines": False,
2995        "null": False,
2996        "serde": False,
2997    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3000class RowFormatSerdeProperty(Property):
3001    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3005class QueryTransform(Expression):
3006    arg_types = {
3007        "expressions": True,
3008        "command_script": True,
3009        "schema": False,
3010        "row_format_before": False,
3011        "record_writer": False,
3012        "row_format_after": False,
3013        "record_reader": False,
3014    }
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):
3017class SampleProperty(Property):
3018    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3022class SecurityProperty(Property):
3023    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3026class SchemaCommentProperty(Property):
3027    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
3030class SerdeProperties(Property):
3031    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3034class SetProperty(Property):
3035    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3038class SharingProperty(Property):
3039    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3042class SetConfigProperty(Property):
3043    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3046class SettingsProperty(Property):
3047    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3050class SortKeyProperty(Property):
3051    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3054class SqlReadWriteProperty(Property):
3055    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3058class SqlSecurityProperty(Property):
3059    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3062class StabilityProperty(Property):
3063    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3066class StorageHandlerProperty(Property):
3067    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3070class TemporaryProperty(Property):
3071    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3074class SecureProperty(Property):
3075    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3079class Tags(ColumnConstraintKind, Property):
3080    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3083class TransformModelProperty(Property):
3084    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3087class TransientProperty(Property):
3088    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3091class UnloggedProperty(Property):
3092    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3096class UsingTemplateProperty(Property):
3097    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3101class ViewAttributeProperty(Property):
3102    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3105class VolatileProperty(Property):
3106    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3109class WithDataProperty(Property):
3110    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3113class WithJournalTableProperty(Property):
3114    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3117class WithSchemaBindingProperty(Property):
3118    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3121class WithSystemVersioningProperty(Property):
3122    arg_types = {
3123        "on": False,
3124        "this": False,
3125        "data_consistency": False,
3126        "retention_period": False,
3127        "with": True,
3128    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3131class WithProcedureOptions(Property):
3132    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3135class EncodeProperty(Property):
3136    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3139class IncludeProperty(Property):
3140    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3143class ForceProperty(Property):
3144    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3147class Properties(Expression):
3148    arg_types = {"expressions": True}
3149
3150    NAME_TO_PROPERTY = {
3151        "ALGORITHM": AlgorithmProperty,
3152        "AUTO_INCREMENT": AutoIncrementProperty,
3153        "CHARACTER SET": CharacterSetProperty,
3154        "CLUSTERED_BY": ClusteredByProperty,
3155        "COLLATE": CollateProperty,
3156        "COMMENT": SchemaCommentProperty,
3157        "CREDENTIALS": CredentialsProperty,
3158        "DEFINER": DefinerProperty,
3159        "DISTKEY": DistKeyProperty,
3160        "DISTRIBUTED_BY": DistributedByProperty,
3161        "DISTSTYLE": DistStyleProperty,
3162        "ENGINE": EngineProperty,
3163        "EXECUTE AS": ExecuteAsProperty,
3164        "FORMAT": FileFormatProperty,
3165        "LANGUAGE": LanguageProperty,
3166        "LOCATION": LocationProperty,
3167        "LOCK": LockProperty,
3168        "PARTITIONED_BY": PartitionedByProperty,
3169        "RETURNS": ReturnsProperty,
3170        "ROW_FORMAT": RowFormatProperty,
3171        "SORTKEY": SortKeyProperty,
3172        "ENCODE": EncodeProperty,
3173        "INCLUDE": IncludeProperty,
3174    }
3175
3176    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3177
3178    # CREATE property locations
3179    # Form: schema specified
3180    #   create [POST_CREATE]
3181    #     table a [POST_NAME]
3182    #     (b int) [POST_SCHEMA]
3183    #     with ([POST_WITH])
3184    #     index (b) [POST_INDEX]
3185    #
3186    # Form: alias selection
3187    #   create [POST_CREATE]
3188    #     table a [POST_NAME]
3189    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3190    #     index (c) [POST_INDEX]
3191    class Location(AutoName):
3192        POST_CREATE = auto()
3193        POST_NAME = auto()
3194        POST_SCHEMA = auto()
3195        POST_WITH = auto()
3196        POST_ALIAS = auto()
3197        POST_EXPRESSION = auto()
3198        POST_INDEX = auto()
3199        UNSUPPORTED = auto()
3200
3201    @classmethod
3202    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3203        expressions = []
3204        for key, value in properties_dict.items():
3205            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3206            if property_cls:
3207                expressions.append(property_cls(this=convert(value)))
3208            else:
3209                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3210
3211        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'>, 'CREDENTIALS': <class 'CredentialsProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>, 'ENCODE': <class 'EncodeProperty'>, 'INCLUDE': <class 'IncludeProperty'>}
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 'CredentialsProperty'>: 'CREDENTIALS', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistributedByProperty'>: 'DISTRIBUTED_BY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY', <class 'EncodeProperty'>: 'ENCODE', <class 'IncludeProperty'>: 'INCLUDE'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3201    @classmethod
3202    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3203        expressions = []
3204        for key, value in properties_dict.items():
3205            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3206            if property_cls:
3207                expressions.append(property_cls(this=convert(value)))
3208            else:
3209                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3210
3211        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3191    class Location(AutoName):
3192        POST_CREATE = auto()
3193        POST_NAME = auto()
3194        POST_SCHEMA = auto()
3195        POST_WITH = auto()
3196        POST_ALIAS = auto()
3197        POST_EXPRESSION = auto()
3198        POST_INDEX = auto()
3199        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'>
class Qualify(Expression):
3214class Qualify(Expression):
3215    pass
key = 'qualify'
class InputOutputFormat(Expression):
3218class InputOutputFormat(Expression):
3219    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3223class Return(Expression):
3224    pass
key = 'return'
class Reference(Expression):
3227class Reference(Expression):
3228    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3231class Tuple(Expression):
3232    arg_types = {"expressions": False}
3233
3234    def isin(
3235        self,
3236        *expressions: t.Any,
3237        query: t.Optional[ExpOrStr] = None,
3238        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3239        copy: bool = True,
3240        **opts,
3241    ) -> In:
3242        return In(
3243            this=maybe_copy(self, copy),
3244            expressions=[convert(e, copy=copy) for e in expressions],
3245            query=maybe_parse(query, copy=copy, **opts) if query else None,
3246            unnest=(
3247                Unnest(
3248                    expressions=[
3249                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3250                        for e in ensure_list(unnest)
3251                    ]
3252                )
3253                if unnest
3254                else None
3255            ),
3256        )
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:
3234    def isin(
3235        self,
3236        *expressions: t.Any,
3237        query: t.Optional[ExpOrStr] = None,
3238        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3239        copy: bool = True,
3240        **opts,
3241    ) -> In:
3242        return In(
3243            this=maybe_copy(self, copy),
3244            expressions=[convert(e, copy=copy) for e in expressions],
3245            query=maybe_parse(query, copy=copy, **opts) if query else None,
3246            unnest=(
3247                Unnest(
3248                    expressions=[
3249                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3250                        for e in ensure_list(unnest)
3251                    ]
3252                )
3253                if unnest
3254                else None
3255            ),
3256        )
key = 'tuple'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': 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, 'options': False}
class QueryOption(Expression):
3287class QueryOption(Expression):
3288    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3292class WithTableHint(Expression):
3293    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3297class IndexTableHint(Expression):
3298    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3302class HistoricalData(Expression):
3303    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3307class Put(Expression):
3308    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Table(Expression):
3311class Table(Expression):
3312    arg_types = {
3313        "this": False,
3314        "alias": False,
3315        "db": False,
3316        "catalog": False,
3317        "laterals": False,
3318        "joins": False,
3319        "pivots": False,
3320        "hints": False,
3321        "system_time": False,
3322        "version": False,
3323        "format": False,
3324        "pattern": False,
3325        "ordinality": False,
3326        "when": False,
3327        "only": False,
3328        "partition": False,
3329        "changes": False,
3330        "rows_from": False,
3331        "sample": False,
3332    }
3333
3334    @property
3335    def name(self) -> str:
3336        if not self.this or isinstance(self.this, Func):
3337            return ""
3338        return self.this.name
3339
3340    @property
3341    def db(self) -> str:
3342        return self.text("db")
3343
3344    @property
3345    def catalog(self) -> str:
3346        return self.text("catalog")
3347
3348    @property
3349    def selects(self) -> t.List[Expression]:
3350        return []
3351
3352    @property
3353    def named_selects(self) -> t.List[str]:
3354        return []
3355
3356    @property
3357    def parts(self) -> t.List[Expression]:
3358        """Return the parts of a table in order catalog, db, table."""
3359        parts: t.List[Expression] = []
3360
3361        for arg in ("catalog", "db", "this"):
3362            part = self.args.get(arg)
3363
3364            if isinstance(part, Dot):
3365                parts.extend(part.flatten())
3366            elif isinstance(part, Expression):
3367                parts.append(part)
3368
3369        return parts
3370
3371    def to_column(self, copy: bool = True) -> Expression:
3372        parts = self.parts
3373        last_part = parts[-1]
3374
3375        if isinstance(last_part, Identifier):
3376            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3377        else:
3378            # This branch will be reached if a function or array is wrapped in a `Table`
3379            col = last_part
3380
3381        alias = self.args.get("alias")
3382        if alias:
3383            col = alias_(col, alias.this, copy=copy)
3384
3385        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False, 'partition': False, 'changes': False, 'rows_from': False, 'sample': False}
name: str
3334    @property
3335    def name(self) -> str:
3336        if not self.this or isinstance(self.this, Func):
3337            return ""
3338        return self.this.name
db: str
3340    @property
3341    def db(self) -> str:
3342        return self.text("db")
catalog: str
3344    @property
3345    def catalog(self) -> str:
3346        return self.text("catalog")
selects: List[Expression]
3348    @property
3349    def selects(self) -> t.List[Expression]:
3350        return []
named_selects: List[str]
3352    @property
3353    def named_selects(self) -> t.List[str]:
3354        return []
parts: List[Expression]
3356    @property
3357    def parts(self) -> t.List[Expression]:
3358        """Return the parts of a table in order catalog, db, table."""
3359        parts: t.List[Expression] = []
3360
3361        for arg in ("catalog", "db", "this"):
3362            part = self.args.get(arg)
3363
3364            if isinstance(part, Dot):
3365                parts.extend(part.flatten())
3366            elif isinstance(part, Expression):
3367                parts.append(part)
3368
3369        return parts

Return the parts of a table in order catalog, db, table.

def to_column(self, copy: bool = True) -> Expression:
3371    def to_column(self, copy: bool = True) -> Expression:
3372        parts = self.parts
3373        last_part = parts[-1]
3374
3375        if isinstance(last_part, Identifier):
3376            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3377        else:
3378            # This branch will be reached if a function or array is wrapped in a `Table`
3379            col = last_part
3380
3381        alias = self.args.get("alias")
3382        if alias:
3383            col = alias_(col, alias.this, copy=copy)
3384
3385        return col
key = 'table'
class SetOperation(Query):
3388class SetOperation(Query):
3389    arg_types = {
3390        "with": False,
3391        "this": True,
3392        "expression": True,
3393        "distinct": False,
3394        "by_name": False,
3395        "side": False,
3396        "kind": False,
3397        "on": False,
3398        **QUERY_MODIFIERS,
3399    }
3400
3401    def select(
3402        self: S,
3403        *expressions: t.Optional[ExpOrStr],
3404        append: bool = True,
3405        dialect: DialectType = None,
3406        copy: bool = True,
3407        **opts,
3408    ) -> S:
3409        this = maybe_copy(self, copy)
3410        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3411        this.expression.unnest().select(
3412            *expressions, append=append, dialect=dialect, copy=False, **opts
3413        )
3414        return this
3415
3416    @property
3417    def named_selects(self) -> t.List[str]:
3418        return self.this.unnest().named_selects
3419
3420    @property
3421    def is_star(self) -> bool:
3422        return self.this.is_star or self.expression.is_star
3423
3424    @property
3425    def selects(self) -> t.List[Expression]:
3426        return self.this.unnest().selects
3427
3428    @property
3429    def left(self) -> Query:
3430        return self.this
3431
3432    @property
3433    def right(self) -> Query:
3434        return self.expression
3435
3436    @property
3437    def kind(self) -> str:
3438        return self.text("kind").upper()
3439
3440    @property
3441    def side(self) -> str:
3442        return self.text("side").upper()
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': 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, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3401    def select(
3402        self: S,
3403        *expressions: t.Optional[ExpOrStr],
3404        append: bool = True,
3405        dialect: DialectType = None,
3406        copy: bool = True,
3407        **opts,
3408    ) -> S:
3409        this = maybe_copy(self, copy)
3410        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3411        this.expression.unnest().select(
3412            *expressions, append=append, dialect=dialect, copy=False, **opts
3413        )
3414        return this

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 Query expression.

named_selects: List[str]
3416    @property
3417    def named_selects(self) -> t.List[str]:
3418        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3420    @property
3421    def is_star(self) -> bool:
3422        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3424    @property
3425    def selects(self) -> t.List[Expression]:
3426        return self.this.unnest().selects

Returns the query's projections.

left: Query
3428    @property
3429    def left(self) -> Query:
3430        return self.this
right: Query
3432    @property
3433    def right(self) -> Query:
3434        return self.expression
kind: str
3436    @property
3437    def kind(self) -> str:
3438        return self.text("kind").upper()
side: str
3440    @property
3441    def side(self) -> str:
3442        return self.text("side").upper()
key = 'setoperation'
class Union(SetOperation):
3445class Union(SetOperation):
3446    pass
key = 'union'
class Except(SetOperation):
3449class Except(SetOperation):
3450    pass
key = 'except'
class Intersect(SetOperation):
3453class Intersect(SetOperation):
3454    pass
key = 'intersect'
class Update(DML):
3457class Update(DML):
3458    arg_types = {
3459        "with": False,
3460        "this": False,
3461        "expressions": True,
3462        "from": False,
3463        "where": False,
3464        "returning": False,
3465        "order": False,
3466        "limit": False,
3467    }
3468
3469    def table(
3470        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3471    ) -> Update:
3472        """
3473        Set the table to update.
3474
3475        Example:
3476            >>> Update().table("my_table").set_("x = 1").sql()
3477            'UPDATE my_table SET x = 1'
3478
3479        Args:
3480            expression : the SQL code strings to parse.
3481                If a `Table` instance is passed, this is used as-is.
3482                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3483            dialect: the dialect used to parse the input expression.
3484            copy: if `False`, modify this expression instance in-place.
3485            opts: other options to use to parse the input expressions.
3486
3487        Returns:
3488            The modified Update expression.
3489        """
3490        return _apply_builder(
3491            expression=expression,
3492            instance=self,
3493            arg="this",
3494            into=Table,
3495            prefix=None,
3496            dialect=dialect,
3497            copy=copy,
3498            **opts,
3499        )
3500
3501    def set_(
3502        self,
3503        *expressions: ExpOrStr,
3504        append: bool = True,
3505        dialect: DialectType = None,
3506        copy: bool = True,
3507        **opts,
3508    ) -> Update:
3509        """
3510        Append to or set the SET expressions.
3511
3512        Example:
3513            >>> Update().table("my_table").set_("x = 1").sql()
3514            'UPDATE my_table SET x = 1'
3515
3516        Args:
3517            *expressions: the SQL code strings to parse.
3518                If `Expression` instance(s) are passed, they will be used as-is.
3519                Multiple expressions are combined with a comma.
3520            append: if `True`, add the new expressions to any existing SET expressions.
3521                Otherwise, this resets the expressions.
3522            dialect: the dialect used to parse the input expressions.
3523            copy: if `False`, modify this expression instance in-place.
3524            opts: other options to use to parse the input expressions.
3525        """
3526        return _apply_list_builder(
3527            *expressions,
3528            instance=self,
3529            arg="expressions",
3530            append=append,
3531            into=Expression,
3532            prefix=None,
3533            dialect=dialect,
3534            copy=copy,
3535            **opts,
3536        )
3537
3538    def where(
3539        self,
3540        *expressions: t.Optional[ExpOrStr],
3541        append: bool = True,
3542        dialect: DialectType = None,
3543        copy: bool = True,
3544        **opts,
3545    ) -> Select:
3546        """
3547        Append to or set the WHERE expressions.
3548
3549        Example:
3550            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3551            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3552
3553        Args:
3554            *expressions: the SQL code strings to parse.
3555                If an `Expression` instance is passed, it will be used as-is.
3556                Multiple expressions are combined with an AND operator.
3557            append: if `True`, AND the new expressions to any existing expression.
3558                Otherwise, this resets the expression.
3559            dialect: the dialect used to parse the input expressions.
3560            copy: if `False`, modify this expression instance in-place.
3561            opts: other options to use to parse the input expressions.
3562
3563        Returns:
3564            Select: the modified expression.
3565        """
3566        return _apply_conjunction_builder(
3567            *expressions,
3568            instance=self,
3569            arg="where",
3570            append=append,
3571            into=Where,
3572            dialect=dialect,
3573            copy=copy,
3574            **opts,
3575        )
3576
3577    def from_(
3578        self,
3579        expression: t.Optional[ExpOrStr] = None,
3580        dialect: DialectType = None,
3581        copy: bool = True,
3582        **opts,
3583    ) -> Update:
3584        """
3585        Set the FROM expression.
3586
3587        Example:
3588            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3589            'UPDATE my_table SET x = 1 FROM baz'
3590
3591        Args:
3592            expression : the SQL code strings to parse.
3593                If a `From` instance is passed, this is used as-is.
3594                If another `Expression` instance is passed, it will be wrapped in a `From`.
3595                If nothing is passed in then a from is not applied to the expression
3596            dialect: the dialect used to parse the input expression.
3597            copy: if `False`, modify this expression instance in-place.
3598            opts: other options to use to parse the input expressions.
3599
3600        Returns:
3601            The modified Update expression.
3602        """
3603        if not expression:
3604            return maybe_copy(self, copy)
3605
3606        return _apply_builder(
3607            expression=expression,
3608            instance=self,
3609            arg="from",
3610            into=From,
3611            prefix="FROM",
3612            dialect=dialect,
3613            copy=copy,
3614            **opts,
3615        )
3616
3617    def with_(
3618        self,
3619        alias: ExpOrStr,
3620        as_: ExpOrStr,
3621        recursive: t.Optional[bool] = None,
3622        materialized: t.Optional[bool] = None,
3623        append: bool = True,
3624        dialect: DialectType = None,
3625        copy: bool = True,
3626        **opts,
3627    ) -> Update:
3628        """
3629        Append to or set the common table expressions.
3630
3631        Example:
3632            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3633            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3634
3635        Args:
3636            alias: the SQL code string to parse as the table name.
3637                If an `Expression` instance is passed, this is used as-is.
3638            as_: the SQL code string to parse as the table expression.
3639                If an `Expression` instance is passed, it will be used as-is.
3640            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3641            materialized: set the MATERIALIZED part of the expression.
3642            append: if `True`, add to any existing expressions.
3643                Otherwise, this resets the expressions.
3644            dialect: the dialect used to parse the input expression.
3645            copy: if `False`, modify this expression instance in-place.
3646            opts: other options to use to parse the input expressions.
3647
3648        Returns:
3649            The modified expression.
3650        """
3651        return _apply_cte_builder(
3652            self,
3653            alias,
3654            as_,
3655            recursive=recursive,
3656            materialized=materialized,
3657            append=append,
3658            dialect=dialect,
3659            copy=copy,
3660            **opts,
3661        )
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
def table( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3469    def table(
3470        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3471    ) -> Update:
3472        """
3473        Set the table to update.
3474
3475        Example:
3476            >>> Update().table("my_table").set_("x = 1").sql()
3477            'UPDATE my_table SET x = 1'
3478
3479        Args:
3480            expression : the SQL code strings to parse.
3481                If a `Table` instance is passed, this is used as-is.
3482                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3483            dialect: the dialect used to parse the input expression.
3484            copy: if `False`, modify this expression instance in-place.
3485            opts: other options to use to parse the input expressions.
3486
3487        Returns:
3488            The modified Update expression.
3489        """
3490        return _apply_builder(
3491            expression=expression,
3492            instance=self,
3493            arg="this",
3494            into=Table,
3495            prefix=None,
3496            dialect=dialect,
3497            copy=copy,
3498            **opts,
3499        )

Set the table to update.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • expression : the SQL code strings to parse. If a Table instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Table.
  • 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 Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3501    def set_(
3502        self,
3503        *expressions: ExpOrStr,
3504        append: bool = True,
3505        dialect: DialectType = None,
3506        copy: bool = True,
3507        **opts,
3508    ) -> Update:
3509        """
3510        Append to or set the SET expressions.
3511
3512        Example:
3513            >>> Update().table("my_table").set_("x = 1").sql()
3514            'UPDATE my_table SET x = 1'
3515
3516        Args:
3517            *expressions: the SQL code strings to parse.
3518                If `Expression` instance(s) are passed, they will be used as-is.
3519                Multiple expressions are combined with a comma.
3520            append: if `True`, add the new expressions to any existing SET expressions.
3521                Otherwise, this resets the expressions.
3522            dialect: the dialect used to parse the input expressions.
3523            copy: if `False`, modify this expression instance in-place.
3524            opts: other options to use to parse the input expressions.
3525        """
3526        return _apply_list_builder(
3527            *expressions,
3528            instance=self,
3529            arg="expressions",
3530            append=append,
3531            into=Expression,
3532            prefix=None,
3533            dialect=dialect,
3534            copy=copy,
3535            **opts,
3536        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET 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.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3538    def where(
3539        self,
3540        *expressions: t.Optional[ExpOrStr],
3541        append: bool = True,
3542        dialect: DialectType = None,
3543        copy: bool = True,
3544        **opts,
3545    ) -> Select:
3546        """
3547        Append to or set the WHERE expressions.
3548
3549        Example:
3550            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3551            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3552
3553        Args:
3554            *expressions: the SQL code strings to parse.
3555                If an `Expression` instance is passed, it will be used as-is.
3556                Multiple expressions are combined with an AND operator.
3557            append: if `True`, AND the new expressions to any existing expression.
3558                Otherwise, this resets the expression.
3559            dialect: the dialect used to parse the input expressions.
3560            copy: if `False`, modify this expression instance in-place.
3561            opts: other options to use to parse the input expressions.
3562
3563        Returns:
3564            Select: the modified expression.
3565        """
3566        return _apply_conjunction_builder(
3567            *expressions,
3568            instance=self,
3569            arg="where",
3570            append=append,
3571            into=Where,
3572            dialect=dialect,
3573            copy=copy,
3574            **opts,
3575        )

Append to or set the WHERE expressions.

Example:
>>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
"UPDATE tbl SET x = 1 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 from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3577    def from_(
3578        self,
3579        expression: t.Optional[ExpOrStr] = None,
3580        dialect: DialectType = None,
3581        copy: bool = True,
3582        **opts,
3583    ) -> Update:
3584        """
3585        Set the FROM expression.
3586
3587        Example:
3588            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3589            'UPDATE my_table SET x = 1 FROM baz'
3590
3591        Args:
3592            expression : the SQL code strings to parse.
3593                If a `From` instance is passed, this is used as-is.
3594                If another `Expression` instance is passed, it will be wrapped in a `From`.
3595                If nothing is passed in then a from is not applied to the expression
3596            dialect: the dialect used to parse the input expression.
3597            copy: if `False`, modify this expression instance in-place.
3598            opts: other options to use to parse the input expressions.
3599
3600        Returns:
3601            The modified Update expression.
3602        """
3603        if not expression:
3604            return maybe_copy(self, copy)
3605
3606        return _apply_builder(
3607            expression=expression,
3608            instance=self,
3609            arg="from",
3610            into=From,
3611            prefix="FROM",
3612            dialect=dialect,
3613            copy=copy,
3614            **opts,
3615        )

Set the FROM expression.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").sql()
'UPDATE my_table SET x = 1 FROM baz'
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. If nothing is passed in then a from is not applied to the 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 Update expression.

def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3617    def with_(
3618        self,
3619        alias: ExpOrStr,
3620        as_: ExpOrStr,
3621        recursive: t.Optional[bool] = None,
3622        materialized: t.Optional[bool] = None,
3623        append: bool = True,
3624        dialect: DialectType = None,
3625        copy: bool = True,
3626        **opts,
3627    ) -> Update:
3628        """
3629        Append to or set the common table expressions.
3630
3631        Example:
3632            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3633            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3634
3635        Args:
3636            alias: the SQL code string to parse as the table name.
3637                If an `Expression` instance is passed, this is used as-is.
3638            as_: the SQL code string to parse as the table expression.
3639                If an `Expression` instance is passed, it will be used as-is.
3640            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3641            materialized: set the MATERIALIZED part of the expression.
3642            append: if `True`, add to any existing expressions.
3643                Otherwise, this resets the expressions.
3644            dialect: the dialect used to parse the input expression.
3645            copy: if `False`, modify this expression instance in-place.
3646            opts: other options to use to parse the input expressions.
3647
3648        Returns:
3649            The modified expression.
3650        """
3651        return _apply_cte_builder(
3652            self,
3653            alias,
3654            as_,
3655            recursive=recursive,
3656            materialized=materialized,
3657            append=append,
3658            dialect=dialect,
3659            copy=copy,
3660            **opts,
3661        )

Append to or set the common table expressions.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
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.
  • materialized: set the MATERIALIZED part of the expression.
  • 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 = 'update'
class Values(UDTF):
3664class Values(UDTF):
3665    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3668class Var(Expression):
3669    pass
key = 'var'
class Version(Expression):
3672class Version(Expression):
3673    """
3674    Time travel, iceberg, bigquery etc
3675    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3676    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3677    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3678    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3679    this is either TIMESTAMP or VERSION
3680    kind is ("AS OF", "BETWEEN")
3681    """
3682
3683    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3686class Schema(Expression):
3687    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3692class Lock(Expression):
3693    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3696class Select(Query):
3697    arg_types = {
3698        "with": False,
3699        "kind": False,
3700        "expressions": False,
3701        "hint": False,
3702        "distinct": False,
3703        "into": False,
3704        "from": False,
3705        "operation_modifiers": False,
3706        **QUERY_MODIFIERS,
3707    }
3708
3709    def from_(
3710        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3711    ) -> Select:
3712        """
3713        Set the FROM expression.
3714
3715        Example:
3716            >>> Select().from_("tbl").select("x").sql()
3717            'SELECT x FROM tbl'
3718
3719        Args:
3720            expression : the SQL code strings to parse.
3721                If a `From` instance is passed, this is used as-is.
3722                If another `Expression` instance is passed, it will be wrapped in a `From`.
3723            dialect: the dialect used to parse the input expression.
3724            copy: if `False`, modify this expression instance in-place.
3725            opts: other options to use to parse the input expressions.
3726
3727        Returns:
3728            The modified Select expression.
3729        """
3730        return _apply_builder(
3731            expression=expression,
3732            instance=self,
3733            arg="from",
3734            into=From,
3735            prefix="FROM",
3736            dialect=dialect,
3737            copy=copy,
3738            **opts,
3739        )
3740
3741    def group_by(
3742        self,
3743        *expressions: t.Optional[ExpOrStr],
3744        append: bool = True,
3745        dialect: DialectType = None,
3746        copy: bool = True,
3747        **opts,
3748    ) -> Select:
3749        """
3750        Set the GROUP BY expression.
3751
3752        Example:
3753            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3754            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3755
3756        Args:
3757            *expressions: the SQL code strings to parse.
3758                If a `Group` instance is passed, this is used as-is.
3759                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3760                If nothing is passed in then a group by is not applied to the expression
3761            append: if `True`, add to any existing expressions.
3762                Otherwise, this flattens all the `Group` expression into a single expression.
3763            dialect: the dialect used to parse the input expression.
3764            copy: if `False`, modify this expression instance in-place.
3765            opts: other options to use to parse the input expressions.
3766
3767        Returns:
3768            The modified Select expression.
3769        """
3770        if not expressions:
3771            return self if not copy else self.copy()
3772
3773        return _apply_child_list_builder(
3774            *expressions,
3775            instance=self,
3776            arg="group",
3777            append=append,
3778            copy=copy,
3779            prefix="GROUP BY",
3780            into=Group,
3781            dialect=dialect,
3782            **opts,
3783        )
3784
3785    def sort_by(
3786        self,
3787        *expressions: t.Optional[ExpOrStr],
3788        append: bool = True,
3789        dialect: DialectType = None,
3790        copy: bool = True,
3791        **opts,
3792    ) -> Select:
3793        """
3794        Set the SORT BY expression.
3795
3796        Example:
3797            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3798            'SELECT x FROM tbl SORT BY x DESC'
3799
3800        Args:
3801            *expressions: the SQL code strings to parse.
3802                If a `Group` instance is passed, this is used as-is.
3803                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3804            append: if `True`, add to any existing expressions.
3805                Otherwise, this flattens all the `Order` expression into a single expression.
3806            dialect: the dialect used to parse the input expression.
3807            copy: if `False`, modify this expression instance in-place.
3808            opts: other options to use to parse the input expressions.
3809
3810        Returns:
3811            The modified Select expression.
3812        """
3813        return _apply_child_list_builder(
3814            *expressions,
3815            instance=self,
3816            arg="sort",
3817            append=append,
3818            copy=copy,
3819            prefix="SORT BY",
3820            into=Sort,
3821            dialect=dialect,
3822            **opts,
3823        )
3824
3825    def cluster_by(
3826        self,
3827        *expressions: t.Optional[ExpOrStr],
3828        append: bool = True,
3829        dialect: DialectType = None,
3830        copy: bool = True,
3831        **opts,
3832    ) -> Select:
3833        """
3834        Set the CLUSTER BY expression.
3835
3836        Example:
3837            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3838            'SELECT x FROM tbl CLUSTER BY x DESC'
3839
3840        Args:
3841            *expressions: the SQL code strings to parse.
3842                If a `Group` instance is passed, this is used as-is.
3843                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3844            append: if `True`, add to any existing expressions.
3845                Otherwise, this flattens all the `Order` expression into a single expression.
3846            dialect: the dialect used to parse the input expression.
3847            copy: if `False`, modify this expression instance in-place.
3848            opts: other options to use to parse the input expressions.
3849
3850        Returns:
3851            The modified Select expression.
3852        """
3853        return _apply_child_list_builder(
3854            *expressions,
3855            instance=self,
3856            arg="cluster",
3857            append=append,
3858            copy=copy,
3859            prefix="CLUSTER BY",
3860            into=Cluster,
3861            dialect=dialect,
3862            **opts,
3863        )
3864
3865    def select(
3866        self,
3867        *expressions: t.Optional[ExpOrStr],
3868        append: bool = True,
3869        dialect: DialectType = None,
3870        copy: bool = True,
3871        **opts,
3872    ) -> Select:
3873        return _apply_list_builder(
3874            *expressions,
3875            instance=self,
3876            arg="expressions",
3877            append=append,
3878            dialect=dialect,
3879            into=Expression,
3880            copy=copy,
3881            **opts,
3882        )
3883
3884    def lateral(
3885        self,
3886        *expressions: t.Optional[ExpOrStr],
3887        append: bool = True,
3888        dialect: DialectType = None,
3889        copy: bool = True,
3890        **opts,
3891    ) -> Select:
3892        """
3893        Append to or set the LATERAL expressions.
3894
3895        Example:
3896            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3897            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3898
3899        Args:
3900            *expressions: the SQL code strings to parse.
3901                If an `Expression` instance is passed, it will be used as-is.
3902            append: if `True`, add to any existing expressions.
3903                Otherwise, this resets the expressions.
3904            dialect: the dialect used to parse the input expressions.
3905            copy: if `False`, modify this expression instance in-place.
3906            opts: other options to use to parse the input expressions.
3907
3908        Returns:
3909            The modified Select expression.
3910        """
3911        return _apply_list_builder(
3912            *expressions,
3913            instance=self,
3914            arg="laterals",
3915            append=append,
3916            into=Lateral,
3917            prefix="LATERAL VIEW",
3918            dialect=dialect,
3919            copy=copy,
3920            **opts,
3921        )
3922
3923    def join(
3924        self,
3925        expression: ExpOrStr,
3926        on: t.Optional[ExpOrStr] = None,
3927        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3928        append: bool = True,
3929        join_type: t.Optional[str] = None,
3930        join_alias: t.Optional[Identifier | str] = None,
3931        dialect: DialectType = None,
3932        copy: bool = True,
3933        **opts,
3934    ) -> Select:
3935        """
3936        Append to or set the JOIN expressions.
3937
3938        Example:
3939            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3940            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3941
3942            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3943            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3944
3945            Use `join_type` to change the type of join:
3946
3947            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3948            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3949
3950        Args:
3951            expression: the SQL code string to parse.
3952                If an `Expression` instance is passed, it will be used as-is.
3953            on: optionally specify the join "on" criteria as a SQL string.
3954                If an `Expression` instance is passed, it will be used as-is.
3955            using: optionally specify the join "using" criteria as a SQL string.
3956                If an `Expression` instance is passed, it will be used as-is.
3957            append: if `True`, add to any existing expressions.
3958                Otherwise, this resets the expressions.
3959            join_type: if set, alter the parsed join type.
3960            join_alias: an optional alias for the joined source.
3961            dialect: the dialect used to parse the input expressions.
3962            copy: if `False`, modify this expression instance in-place.
3963            opts: other options to use to parse the input expressions.
3964
3965        Returns:
3966            Select: the modified expression.
3967        """
3968        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3969
3970        try:
3971            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3972        except ParseError:
3973            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3974
3975        join = expression if isinstance(expression, Join) else Join(this=expression)
3976
3977        if isinstance(join.this, Select):
3978            join.this.replace(join.this.subquery())
3979
3980        if join_type:
3981            method: t.Optional[Token]
3982            side: t.Optional[Token]
3983            kind: t.Optional[Token]
3984
3985            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3986
3987            if method:
3988                join.set("method", method.text)
3989            if side:
3990                join.set("side", side.text)
3991            if kind:
3992                join.set("kind", kind.text)
3993
3994        if on:
3995            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3996            join.set("on", on)
3997
3998        if using:
3999            join = _apply_list_builder(
4000                *ensure_list(using),
4001                instance=join,
4002                arg="using",
4003                append=append,
4004                copy=copy,
4005                into=Identifier,
4006                **opts,
4007            )
4008
4009        if join_alias:
4010            join.set("this", alias_(join.this, join_alias, table=True))
4011
4012        return _apply_list_builder(
4013            join,
4014            instance=self,
4015            arg="joins",
4016            append=append,
4017            copy=copy,
4018            **opts,
4019        )
4020
4021    def where(
4022        self,
4023        *expressions: t.Optional[ExpOrStr],
4024        append: bool = True,
4025        dialect: DialectType = None,
4026        copy: bool = True,
4027        **opts,
4028    ) -> Select:
4029        """
4030        Append to or set the WHERE expressions.
4031
4032        Example:
4033            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
4034            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
4035
4036        Args:
4037            *expressions: the SQL code strings to parse.
4038                If an `Expression` instance is passed, it will be used as-is.
4039                Multiple expressions are combined with an AND operator.
4040            append: if `True`, AND the new expressions to any existing expression.
4041                Otherwise, this resets the expression.
4042            dialect: the dialect used to parse the input expressions.
4043            copy: if `False`, modify this expression instance in-place.
4044            opts: other options to use to parse the input expressions.
4045
4046        Returns:
4047            Select: the modified expression.
4048        """
4049        return _apply_conjunction_builder(
4050            *expressions,
4051            instance=self,
4052            arg="where",
4053            append=append,
4054            into=Where,
4055            dialect=dialect,
4056            copy=copy,
4057            **opts,
4058        )
4059
4060    def having(
4061        self,
4062        *expressions: t.Optional[ExpOrStr],
4063        append: bool = True,
4064        dialect: DialectType = None,
4065        copy: bool = True,
4066        **opts,
4067    ) -> Select:
4068        """
4069        Append to or set the HAVING expressions.
4070
4071        Example:
4072            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4073            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4074
4075        Args:
4076            *expressions: the SQL code strings to parse.
4077                If an `Expression` instance is passed, it will be used as-is.
4078                Multiple expressions are combined with an AND operator.
4079            append: if `True`, AND the new expressions to any existing expression.
4080                Otherwise, this resets the expression.
4081            dialect: the dialect used to parse the input expressions.
4082            copy: if `False`, modify this expression instance in-place.
4083            opts: other options to use to parse the input expressions.
4084
4085        Returns:
4086            The modified Select expression.
4087        """
4088        return _apply_conjunction_builder(
4089            *expressions,
4090            instance=self,
4091            arg="having",
4092            append=append,
4093            into=Having,
4094            dialect=dialect,
4095            copy=copy,
4096            **opts,
4097        )
4098
4099    def window(
4100        self,
4101        *expressions: t.Optional[ExpOrStr],
4102        append: bool = True,
4103        dialect: DialectType = None,
4104        copy: bool = True,
4105        **opts,
4106    ) -> Select:
4107        return _apply_list_builder(
4108            *expressions,
4109            instance=self,
4110            arg="windows",
4111            append=append,
4112            into=Window,
4113            dialect=dialect,
4114            copy=copy,
4115            **opts,
4116        )
4117
4118    def qualify(
4119        self,
4120        *expressions: t.Optional[ExpOrStr],
4121        append: bool = True,
4122        dialect: DialectType = None,
4123        copy: bool = True,
4124        **opts,
4125    ) -> Select:
4126        return _apply_conjunction_builder(
4127            *expressions,
4128            instance=self,
4129            arg="qualify",
4130            append=append,
4131            into=Qualify,
4132            dialect=dialect,
4133            copy=copy,
4134            **opts,
4135        )
4136
4137    def distinct(
4138        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4139    ) -> Select:
4140        """
4141        Set the OFFSET expression.
4142
4143        Example:
4144            >>> Select().from_("tbl").select("x").distinct().sql()
4145            'SELECT DISTINCT x FROM tbl'
4146
4147        Args:
4148            ons: the expressions to distinct on
4149            distinct: whether the Select should be distinct
4150            copy: if `False`, modify this expression instance in-place.
4151
4152        Returns:
4153            Select: the modified expression.
4154        """
4155        instance = maybe_copy(self, copy)
4156        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4157        instance.set("distinct", Distinct(on=on) if distinct else None)
4158        return instance
4159
4160    def ctas(
4161        self,
4162        table: ExpOrStr,
4163        properties: t.Optional[t.Dict] = None,
4164        dialect: DialectType = None,
4165        copy: bool = True,
4166        **opts,
4167    ) -> Create:
4168        """
4169        Convert this expression to a CREATE TABLE AS statement.
4170
4171        Example:
4172            >>> Select().select("*").from_("tbl").ctas("x").sql()
4173            'CREATE TABLE x AS SELECT * FROM tbl'
4174
4175        Args:
4176            table: the SQL code string to parse as the table name.
4177                If another `Expression` instance is passed, it will be used as-is.
4178            properties: an optional mapping of table properties
4179            dialect: the dialect used to parse the input table.
4180            copy: if `False`, modify this expression instance in-place.
4181            opts: other options to use to parse the input table.
4182
4183        Returns:
4184            The new Create expression.
4185        """
4186        instance = maybe_copy(self, copy)
4187        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4188
4189        properties_expression = None
4190        if properties:
4191            properties_expression = Properties.from_dict(properties)
4192
4193        return Create(
4194            this=table_expression,
4195            kind="TABLE",
4196            expression=instance,
4197            properties=properties_expression,
4198        )
4199
4200    def lock(self, update: bool = True, copy: bool = True) -> Select:
4201        """
4202        Set the locking read mode for this expression.
4203
4204        Examples:
4205            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4206            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4207
4208            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4209            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4210
4211        Args:
4212            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4213            copy: if `False`, modify this expression instance in-place.
4214
4215        Returns:
4216            The modified expression.
4217        """
4218        inst = maybe_copy(self, copy)
4219        inst.set("locks", [Lock(update=update)])
4220
4221        return inst
4222
4223    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4224        """
4225        Set hints for this expression.
4226
4227        Examples:
4228            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4229            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4230
4231        Args:
4232            hints: The SQL code strings to parse as the hints.
4233                If an `Expression` instance is passed, it will be used as-is.
4234            dialect: The dialect used to parse the hints.
4235            copy: If `False`, modify this expression instance in-place.
4236
4237        Returns:
4238            The modified expression.
4239        """
4240        inst = maybe_copy(self, copy)
4241        inst.set(
4242            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4243        )
4244
4245        return inst
4246
4247    @property
4248    def named_selects(self) -> t.List[str]:
4249        return [e.output_name for e in self.expressions if e.alias_or_name]
4250
4251    @property
4252    def is_star(self) -> bool:
4253        return any(expression.is_star for expression in self.expressions)
4254
4255    @property
4256    def selects(self) -> t.List[Expression]:
4257        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': False, 'operation_modifiers': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': 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, 'options': False}
def from_( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3709    def from_(
3710        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3711    ) -> Select:
3712        """
3713        Set the FROM expression.
3714
3715        Example:
3716            >>> Select().from_("tbl").select("x").sql()
3717            'SELECT x FROM tbl'
3718
3719        Args:
3720            expression : the SQL code strings to parse.
3721                If a `From` instance is passed, this is used as-is.
3722                If another `Expression` instance is passed, it will be wrapped in a `From`.
3723            dialect: the dialect used to parse the input expression.
3724            copy: if `False`, modify this expression instance in-place.
3725            opts: other options to use to parse the input expressions.
3726
3727        Returns:
3728            The modified Select expression.
3729        """
3730        return _apply_builder(
3731            expression=expression,
3732            instance=self,
3733            arg="from",
3734            into=From,
3735            prefix="FROM",
3736            dialect=dialect,
3737            copy=copy,
3738            **opts,
3739        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3741    def group_by(
3742        self,
3743        *expressions: t.Optional[ExpOrStr],
3744        append: bool = True,
3745        dialect: DialectType = None,
3746        copy: bool = True,
3747        **opts,
3748    ) -> Select:
3749        """
3750        Set the GROUP BY expression.
3751
3752        Example:
3753            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3754            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3755
3756        Args:
3757            *expressions: the SQL code strings to parse.
3758                If a `Group` instance is passed, this is used as-is.
3759                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3760                If nothing is passed in then a group by is not applied to the expression
3761            append: if `True`, add to any existing expressions.
3762                Otherwise, this flattens all the `Group` expression into a single expression.
3763            dialect: the dialect used to parse the input expression.
3764            copy: if `False`, modify this expression instance in-place.
3765            opts: other options to use to parse the input expressions.
3766
3767        Returns:
3768            The modified Select expression.
3769        """
3770        if not expressions:
3771            return self if not copy else self.copy()
3772
3773        return _apply_child_list_builder(
3774            *expressions,
3775            instance=self,
3776            arg="group",
3777            append=append,
3778            copy=copy,
3779            prefix="GROUP BY",
3780            into=Group,
3781            dialect=dialect,
3782            **opts,
3783        )

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 sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3785    def sort_by(
3786        self,
3787        *expressions: t.Optional[ExpOrStr],
3788        append: bool = True,
3789        dialect: DialectType = None,
3790        copy: bool = True,
3791        **opts,
3792    ) -> Select:
3793        """
3794        Set the SORT BY expression.
3795
3796        Example:
3797            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3798            'SELECT x FROM tbl SORT BY x DESC'
3799
3800        Args:
3801            *expressions: the SQL code strings to parse.
3802                If a `Group` instance is passed, this is used as-is.
3803                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3804            append: if `True`, add to any existing expressions.
3805                Otherwise, this flattens all the `Order` expression into a single expression.
3806            dialect: the dialect used to parse the input expression.
3807            copy: if `False`, modify this expression instance in-place.
3808            opts: other options to use to parse the input expressions.
3809
3810        Returns:
3811            The modified Select expression.
3812        """
3813        return _apply_child_list_builder(
3814            *expressions,
3815            instance=self,
3816            arg="sort",
3817            append=append,
3818            copy=copy,
3819            prefix="SORT BY",
3820            into=Sort,
3821            dialect=dialect,
3822            **opts,
3823        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3825    def cluster_by(
3826        self,
3827        *expressions: t.Optional[ExpOrStr],
3828        append: bool = True,
3829        dialect: DialectType = None,
3830        copy: bool = True,
3831        **opts,
3832    ) -> Select:
3833        """
3834        Set the CLUSTER BY expression.
3835
3836        Example:
3837            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3838            'SELECT x FROM tbl CLUSTER BY x DESC'
3839
3840        Args:
3841            *expressions: the SQL code strings to parse.
3842                If a `Group` instance is passed, this is used as-is.
3843                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3844            append: if `True`, add to any existing expressions.
3845                Otherwise, this flattens all the `Order` expression into a single expression.
3846            dialect: the dialect used to parse the input expression.
3847            copy: if `False`, modify this expression instance in-place.
3848            opts: other options to use to parse the input expressions.
3849
3850        Returns:
3851            The modified Select expression.
3852        """
3853        return _apply_child_list_builder(
3854            *expressions,
3855            instance=self,
3856            arg="cluster",
3857            append=append,
3858            copy=copy,
3859            prefix="CLUSTER BY",
3860            into=Cluster,
3861            dialect=dialect,
3862            **opts,
3863        )

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 select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3865    def select(
3866        self,
3867        *expressions: t.Optional[ExpOrStr],
3868        append: bool = True,
3869        dialect: DialectType = None,
3870        copy: bool = True,
3871        **opts,
3872    ) -> Select:
3873        return _apply_list_builder(
3874            *expressions,
3875            instance=self,
3876            arg="expressions",
3877            append=append,
3878            dialect=dialect,
3879            into=Expression,
3880            copy=copy,
3881            **opts,
3882        )

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 Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3884    def lateral(
3885        self,
3886        *expressions: t.Optional[ExpOrStr],
3887        append: bool = True,
3888        dialect: DialectType = None,
3889        copy: bool = True,
3890        **opts,
3891    ) -> Select:
3892        """
3893        Append to or set the LATERAL expressions.
3894
3895        Example:
3896            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3897            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3898
3899        Args:
3900            *expressions: the SQL code strings to parse.
3901                If an `Expression` instance is passed, it will be used as-is.
3902            append: if `True`, add to any existing expressions.
3903                Otherwise, this resets the expressions.
3904            dialect: the dialect used to parse the input expressions.
3905            copy: if `False`, modify this expression instance in-place.
3906            opts: other options to use to parse the input expressions.
3907
3908        Returns:
3909            The modified Select expression.
3910        """
3911        return _apply_list_builder(
3912            *expressions,
3913            instance=self,
3914            arg="laterals",
3915            append=append,
3916            into=Lateral,
3917            prefix="LATERAL VIEW",
3918            dialect=dialect,
3919            copy=copy,
3920            **opts,
3921        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3923    def join(
3924        self,
3925        expression: ExpOrStr,
3926        on: t.Optional[ExpOrStr] = None,
3927        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3928        append: bool = True,
3929        join_type: t.Optional[str] = None,
3930        join_alias: t.Optional[Identifier | str] = None,
3931        dialect: DialectType = None,
3932        copy: bool = True,
3933        **opts,
3934    ) -> Select:
3935        """
3936        Append to or set the JOIN expressions.
3937
3938        Example:
3939            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3940            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3941
3942            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3943            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3944
3945            Use `join_type` to change the type of join:
3946
3947            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3948            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3949
3950        Args:
3951            expression: the SQL code string to parse.
3952                If an `Expression` instance is passed, it will be used as-is.
3953            on: optionally specify the join "on" criteria as a SQL string.
3954                If an `Expression` instance is passed, it will be used as-is.
3955            using: optionally specify the join "using" criteria as a SQL string.
3956                If an `Expression` instance is passed, it will be used as-is.
3957            append: if `True`, add to any existing expressions.
3958                Otherwise, this resets the expressions.
3959            join_type: if set, alter the parsed join type.
3960            join_alias: an optional alias for the joined source.
3961            dialect: the dialect used to parse the input expressions.
3962            copy: if `False`, modify this expression instance in-place.
3963            opts: other options to use to parse the input expressions.
3964
3965        Returns:
3966            Select: the modified expression.
3967        """
3968        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3969
3970        try:
3971            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3972        except ParseError:
3973            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3974
3975        join = expression if isinstance(expression, Join) else Join(this=expression)
3976
3977        if isinstance(join.this, Select):
3978            join.this.replace(join.this.subquery())
3979
3980        if join_type:
3981            method: t.Optional[Token]
3982            side: t.Optional[Token]
3983            kind: t.Optional[Token]
3984
3985            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3986
3987            if method:
3988                join.set("method", method.text)
3989            if side:
3990                join.set("side", side.text)
3991            if kind:
3992                join.set("kind", kind.text)
3993
3994        if on:
3995            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3996            join.set("on", on)
3997
3998        if using:
3999            join = _apply_list_builder(
4000                *ensure_list(using),
4001                instance=join,
4002                arg="using",
4003                append=append,
4004                copy=copy,
4005                into=Identifier,
4006                **opts,
4007            )
4008
4009        if join_alias:
4010            join.set("this", alias_(join.this, join_alias, table=True))
4011
4012        return _apply_list_builder(
4013            join,
4014            instance=self,
4015            arg="joins",
4016            append=append,
4017            copy=copy,
4018            **opts,
4019        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4021    def where(
4022        self,
4023        *expressions: t.Optional[ExpOrStr],
4024        append: bool = True,
4025        dialect: DialectType = None,
4026        copy: bool = True,
4027        **opts,
4028    ) -> Select:
4029        """
4030        Append to or set the WHERE expressions.
4031
4032        Example:
4033            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
4034            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
4035
4036        Args:
4037            *expressions: the SQL code strings to parse.
4038                If an `Expression` instance is passed, it will be used as-is.
4039                Multiple expressions are combined with an AND operator.
4040            append: if `True`, AND the new expressions to any existing expression.
4041                Otherwise, this resets the expression.
4042            dialect: the dialect used to parse the input expressions.
4043            copy: if `False`, modify this expression instance in-place.
4044            opts: other options to use to parse the input expressions.
4045
4046        Returns:
4047            Select: the modified expression.
4048        """
4049        return _apply_conjunction_builder(
4050            *expressions,
4051            instance=self,
4052            arg="where",
4053            append=append,
4054            into=Where,
4055            dialect=dialect,
4056            copy=copy,
4057            **opts,
4058        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4060    def having(
4061        self,
4062        *expressions: t.Optional[ExpOrStr],
4063        append: bool = True,
4064        dialect: DialectType = None,
4065        copy: bool = True,
4066        **opts,
4067    ) -> Select:
4068        """
4069        Append to or set the HAVING expressions.
4070
4071        Example:
4072            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4073            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4074
4075        Args:
4076            *expressions: the SQL code strings to parse.
4077                If an `Expression` instance is passed, it will be used as-is.
4078                Multiple expressions are combined with an AND operator.
4079            append: if `True`, AND the new expressions to any existing expression.
4080                Otherwise, this resets the expression.
4081            dialect: the dialect used to parse the input expressions.
4082            copy: if `False`, modify this expression instance in-place.
4083            opts: other options to use to parse the input expressions.
4084
4085        Returns:
4086            The modified Select expression.
4087        """
4088        return _apply_conjunction_builder(
4089            *expressions,
4090            instance=self,
4091            arg="having",
4092            append=append,
4093            into=Having,
4094            dialect=dialect,
4095            copy=copy,
4096            **opts,
4097        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4099    def window(
4100        self,
4101        *expressions: t.Optional[ExpOrStr],
4102        append: bool = True,
4103        dialect: DialectType = None,
4104        copy: bool = True,
4105        **opts,
4106    ) -> Select:
4107        return _apply_list_builder(
4108            *expressions,
4109            instance=self,
4110            arg="windows",
4111            append=append,
4112            into=Window,
4113            dialect=dialect,
4114            copy=copy,
4115            **opts,
4116        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4118    def qualify(
4119        self,
4120        *expressions: t.Optional[ExpOrStr],
4121        append: bool = True,
4122        dialect: DialectType = None,
4123        copy: bool = True,
4124        **opts,
4125    ) -> Select:
4126        return _apply_conjunction_builder(
4127            *expressions,
4128            instance=self,
4129            arg="qualify",
4130            append=append,
4131            into=Qualify,
4132            dialect=dialect,
4133            copy=copy,
4134            **opts,
4135        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4137    def distinct(
4138        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4139    ) -> Select:
4140        """
4141        Set the OFFSET expression.
4142
4143        Example:
4144            >>> Select().from_("tbl").select("x").distinct().sql()
4145            'SELECT DISTINCT x FROM tbl'
4146
4147        Args:
4148            ons: the expressions to distinct on
4149            distinct: whether the Select should be distinct
4150            copy: if `False`, modify this expression instance in-place.
4151
4152        Returns:
4153            Select: the modified expression.
4154        """
4155        instance = maybe_copy(self, copy)
4156        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4157        instance.set("distinct", Distinct(on=on) if distinct else None)
4158        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4160    def ctas(
4161        self,
4162        table: ExpOrStr,
4163        properties: t.Optional[t.Dict] = None,
4164        dialect: DialectType = None,
4165        copy: bool = True,
4166        **opts,
4167    ) -> Create:
4168        """
4169        Convert this expression to a CREATE TABLE AS statement.
4170
4171        Example:
4172            >>> Select().select("*").from_("tbl").ctas("x").sql()
4173            'CREATE TABLE x AS SELECT * FROM tbl'
4174
4175        Args:
4176            table: the SQL code string to parse as the table name.
4177                If another `Expression` instance is passed, it will be used as-is.
4178            properties: an optional mapping of table properties
4179            dialect: the dialect used to parse the input table.
4180            copy: if `False`, modify this expression instance in-place.
4181            opts: other options to use to parse the input table.
4182
4183        Returns:
4184            The new Create expression.
4185        """
4186        instance = maybe_copy(self, copy)
4187        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4188
4189        properties_expression = None
4190        if properties:
4191            properties_expression = Properties.from_dict(properties)
4192
4193        return Create(
4194            this=table_expression,
4195            kind="TABLE",
4196            expression=instance,
4197            properties=properties_expression,
4198        )

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:
4200    def lock(self, update: bool = True, copy: bool = True) -> Select:
4201        """
4202        Set the locking read mode for this expression.
4203
4204        Examples:
4205            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4206            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4207
4208            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4209            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4210
4211        Args:
4212            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4213            copy: if `False`, modify this expression instance in-place.
4214
4215        Returns:
4216            The modified expression.
4217        """
4218        inst = maybe_copy(self, copy)
4219        inst.set("locks", [Lock(update=update)])
4220
4221        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Select:
4223    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4224        """
4225        Set hints for this expression.
4226
4227        Examples:
4228            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4229            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4230
4231        Args:
4232            hints: The SQL code strings to parse as the hints.
4233                If an `Expression` instance is passed, it will be used as-is.
4234            dialect: The dialect used to parse the hints.
4235            copy: If `False`, modify this expression instance in-place.
4236
4237        Returns:
4238            The modified expression.
4239        """
4240        inst = maybe_copy(self, copy)
4241        inst.set(
4242            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4243        )
4244
4245        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]
4247    @property
4248    def named_selects(self) -> t.List[str]:
4249        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
4251    @property
4252    def is_star(self) -> bool:
4253        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4255    @property
4256    def selects(self) -> t.List[Expression]:
4257        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4263class Subquery(DerivedTable, Query):
4264    arg_types = {
4265        "this": True,
4266        "alias": False,
4267        "with": False,
4268        **QUERY_MODIFIERS,
4269    }
4270
4271    def unnest(self):
4272        """Returns the first non subquery."""
4273        expression = self
4274        while isinstance(expression, Subquery):
4275            expression = expression.this
4276        return expression
4277
4278    def unwrap(self) -> Subquery:
4279        expression = self
4280        while expression.same_parent and expression.is_wrapper:
4281            expression = t.cast(Subquery, expression.parent)
4282        return expression
4283
4284    def select(
4285        self,
4286        *expressions: t.Optional[ExpOrStr],
4287        append: bool = True,
4288        dialect: DialectType = None,
4289        copy: bool = True,
4290        **opts,
4291    ) -> Subquery:
4292        this = maybe_copy(self, copy)
4293        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4294        return this
4295
4296    @property
4297    def is_wrapper(self) -> bool:
4298        """
4299        Whether this Subquery acts as a simple wrapper around another expression.
4300
4301        SELECT * FROM (((SELECT * FROM t)))
4302                      ^
4303                      This corresponds to a "wrapper" Subquery node
4304        """
4305        return all(v is None for k, v in self.args.items() if k != "this")
4306
4307    @property
4308    def is_star(self) -> bool:
4309        return self.this.is_star
4310
4311    @property
4312    def output_name(self) -> str:
4313        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': 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, 'options': False}
def unnest(self):
4271    def unnest(self):
4272        """Returns the first non subquery."""
4273        expression = self
4274        while isinstance(expression, Subquery):
4275            expression = expression.this
4276        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4278    def unwrap(self) -> Subquery:
4279        expression = self
4280        while expression.same_parent and expression.is_wrapper:
4281            expression = t.cast(Subquery, expression.parent)
4282        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4284    def select(
4285        self,
4286        *expressions: t.Optional[ExpOrStr],
4287        append: bool = True,
4288        dialect: DialectType = None,
4289        copy: bool = True,
4290        **opts,
4291    ) -> Subquery:
4292        this = maybe_copy(self, copy)
4293        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4294        return this

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 Query expression.

is_wrapper: bool
4296    @property
4297    def is_wrapper(self) -> bool:
4298        """
4299        Whether this Subquery acts as a simple wrapper around another expression.
4300
4301        SELECT * FROM (((SELECT * FROM t)))
4302                      ^
4303                      This corresponds to a "wrapper" Subquery node
4304        """
4305        return all(v is None for k, v in self.args.items() if k != "this")

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
4307    @property
4308    def is_star(self) -> bool:
4309        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4311    @property
4312    def output_name(self) -> str:
4313        return self.alias

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):
4316class TableSample(Expression):
4317    arg_types = {
4318        "expressions": False,
4319        "method": False,
4320        "bucket_numerator": False,
4321        "bucket_denominator": False,
4322        "bucket_field": False,
4323        "percent": False,
4324        "rows": False,
4325        "size": False,
4326        "seed": False,
4327    }
arg_types = {'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
4330class Tag(Expression):
4331    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4332
4333    arg_types = {
4334        "this": False,
4335        "prefix": False,
4336        "postfix": False,
4337    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4342class Pivot(Expression):
4343    arg_types = {
4344        "this": False,
4345        "alias": False,
4346        "expressions": False,
4347        "fields": False,
4348        "unpivot": False,
4349        "using": False,
4350        "group": False,
4351        "columns": False,
4352        "include_nulls": False,
4353        "default_on_null": False,
4354        "into": False,
4355    }
4356
4357    @property
4358    def unpivot(self) -> bool:
4359        return bool(self.args.get("unpivot"))
4360
4361    @property
4362    def fields(self) -> t.List[Expression]:
4363        return self.args.get("fields", [])
arg_types = {'this': False, 'alias': False, 'expressions': False, 'fields': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4357    @property
4358    def unpivot(self) -> bool:
4359        return bool(self.args.get("unpivot"))
fields: List[Expression]
4361    @property
4362    def fields(self) -> t.List[Expression]:
4363        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4368class UnpivotColumns(Expression):
4369    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4372class Window(Condition):
4373    arg_types = {
4374        "this": True,
4375        "partition_by": False,
4376        "order": False,
4377        "spec": False,
4378        "alias": False,
4379        "over": False,
4380        "first": False,
4381    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4384class WindowSpec(Expression):
4385    arg_types = {
4386        "kind": False,
4387        "start": False,
4388        "start_side": False,
4389        "end": False,
4390        "end_side": False,
4391    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4394class PreWhere(Expression):
4395    pass
key = 'prewhere'
class Where(Expression):
4398class Where(Expression):
4399    pass
key = 'where'
class Star(Expression):
4402class Star(Expression):
4403    arg_types = {"except": False, "replace": False, "rename": False}
4404
4405    @property
4406    def name(self) -> str:
4407        return "*"
4408
4409    @property
4410    def output_name(self) -> str:
4411        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4405    @property
4406    def name(self) -> str:
4407        return "*"
output_name: str
4409    @property
4410    def output_name(self) -> str:
4411        return self.name

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):
4414class Parameter(Condition):
4415    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4418class SessionParameter(Condition):
4419    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4422class Placeholder(Condition):
4423    arg_types = {"this": False, "kind": False}
4424
4425    @property
4426    def name(self) -> str:
4427        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4425    @property
4426    def name(self) -> str:
4427        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4430class Null(Condition):
4431    arg_types: t.Dict[str, t.Any] = {}
4432
4433    @property
4434    def name(self) -> str:
4435        return "NULL"
4436
4437    def to_py(self) -> Lit[None]:
4438        return None
arg_types: Dict[str, Any] = {}
name: str
4433    @property
4434    def name(self) -> str:
4435        return "NULL"
def to_py(self) -> Literal[None]:
4437    def to_py(self) -> Lit[None]:
4438        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4441class Boolean(Condition):
4442    def to_py(self) -> bool:
4443        return self.this
def to_py(self) -> bool:
4442    def to_py(self) -> bool:
4443        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4446class DataTypeParam(Expression):
4447    arg_types = {"this": True, "expression": False}
4448
4449    @property
4450    def name(self) -> str:
4451        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4449    @property
4450    def name(self) -> str:
4451        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4456class DataType(Expression):
4457    arg_types = {
4458        "this": True,
4459        "expressions": False,
4460        "nested": False,
4461        "values": False,
4462        "prefix": False,
4463        "kind": False,
4464        "nullable": False,
4465    }
4466
4467    class Type(AutoName):
4468        ARRAY = auto()
4469        AGGREGATEFUNCTION = auto()
4470        SIMPLEAGGREGATEFUNCTION = auto()
4471        BIGDECIMAL = auto()
4472        BIGINT = auto()
4473        BIGSERIAL = auto()
4474        BINARY = auto()
4475        BIT = auto()
4476        BLOB = auto()
4477        BOOLEAN = auto()
4478        BPCHAR = auto()
4479        CHAR = auto()
4480        DATE = auto()
4481        DATE32 = auto()
4482        DATEMULTIRANGE = auto()
4483        DATERANGE = auto()
4484        DATETIME = auto()
4485        DATETIME2 = auto()
4486        DATETIME64 = auto()
4487        DECIMAL = auto()
4488        DECIMAL32 = auto()
4489        DECIMAL64 = auto()
4490        DECIMAL128 = auto()
4491        DECIMAL256 = auto()
4492        DOUBLE = auto()
4493        DYNAMIC = auto()
4494        ENUM = auto()
4495        ENUM8 = auto()
4496        ENUM16 = auto()
4497        FIXEDSTRING = auto()
4498        FLOAT = auto()
4499        GEOGRAPHY = auto()
4500        GEOMETRY = auto()
4501        POINT = auto()
4502        RING = auto()
4503        LINESTRING = auto()
4504        MULTILINESTRING = auto()
4505        POLYGON = auto()
4506        MULTIPOLYGON = auto()
4507        HLLSKETCH = auto()
4508        HSTORE = auto()
4509        IMAGE = auto()
4510        INET = auto()
4511        INT = auto()
4512        INT128 = auto()
4513        INT256 = auto()
4514        INT4MULTIRANGE = auto()
4515        INT4RANGE = auto()
4516        INT8MULTIRANGE = auto()
4517        INT8RANGE = auto()
4518        INTERVAL = auto()
4519        IPADDRESS = auto()
4520        IPPREFIX = auto()
4521        IPV4 = auto()
4522        IPV6 = auto()
4523        JSON = auto()
4524        JSONB = auto()
4525        LIST = auto()
4526        LONGBLOB = auto()
4527        LONGTEXT = auto()
4528        LOWCARDINALITY = auto()
4529        MAP = auto()
4530        MEDIUMBLOB = auto()
4531        MEDIUMINT = auto()
4532        MEDIUMTEXT = auto()
4533        MONEY = auto()
4534        NAME = auto()
4535        NCHAR = auto()
4536        NESTED = auto()
4537        NOTHING = auto()
4538        NULL = auto()
4539        NUMMULTIRANGE = auto()
4540        NUMRANGE = auto()
4541        NVARCHAR = auto()
4542        OBJECT = auto()
4543        RANGE = auto()
4544        ROWVERSION = auto()
4545        SERIAL = auto()
4546        SET = auto()
4547        SMALLDATETIME = auto()
4548        SMALLINT = auto()
4549        SMALLMONEY = auto()
4550        SMALLSERIAL = auto()
4551        STRUCT = auto()
4552        SUPER = auto()
4553        TEXT = auto()
4554        TINYBLOB = auto()
4555        TINYTEXT = auto()
4556        TIME = auto()
4557        TIMETZ = auto()
4558        TIMESTAMP = auto()
4559        TIMESTAMPNTZ = auto()
4560        TIMESTAMPLTZ = auto()
4561        TIMESTAMPTZ = auto()
4562        TIMESTAMP_S = auto()
4563        TIMESTAMP_MS = auto()
4564        TIMESTAMP_NS = auto()
4565        TINYINT = auto()
4566        TSMULTIRANGE = auto()
4567        TSRANGE = auto()
4568        TSTZMULTIRANGE = auto()
4569        TSTZRANGE = auto()
4570        UBIGINT = auto()
4571        UINT = auto()
4572        UINT128 = auto()
4573        UINT256 = auto()
4574        UMEDIUMINT = auto()
4575        UDECIMAL = auto()
4576        UDOUBLE = auto()
4577        UNION = auto()
4578        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4579        USERDEFINED = "USER-DEFINED"
4580        USMALLINT = auto()
4581        UTINYINT = auto()
4582        UUID = auto()
4583        VARBINARY = auto()
4584        VARCHAR = auto()
4585        VARIANT = auto()
4586        VECTOR = auto()
4587        XML = auto()
4588        YEAR = auto()
4589        TDIGEST = auto()
4590
4591    STRUCT_TYPES = {
4592        Type.NESTED,
4593        Type.OBJECT,
4594        Type.STRUCT,
4595        Type.UNION,
4596    }
4597
4598    ARRAY_TYPES = {
4599        Type.ARRAY,
4600        Type.LIST,
4601    }
4602
4603    NESTED_TYPES = {
4604        *STRUCT_TYPES,
4605        *ARRAY_TYPES,
4606        Type.MAP,
4607    }
4608
4609    TEXT_TYPES = {
4610        Type.CHAR,
4611        Type.NCHAR,
4612        Type.NVARCHAR,
4613        Type.TEXT,
4614        Type.VARCHAR,
4615        Type.NAME,
4616    }
4617
4618    SIGNED_INTEGER_TYPES = {
4619        Type.BIGINT,
4620        Type.INT,
4621        Type.INT128,
4622        Type.INT256,
4623        Type.MEDIUMINT,
4624        Type.SMALLINT,
4625        Type.TINYINT,
4626    }
4627
4628    UNSIGNED_INTEGER_TYPES = {
4629        Type.UBIGINT,
4630        Type.UINT,
4631        Type.UINT128,
4632        Type.UINT256,
4633        Type.UMEDIUMINT,
4634        Type.USMALLINT,
4635        Type.UTINYINT,
4636    }
4637
4638    INTEGER_TYPES = {
4639        *SIGNED_INTEGER_TYPES,
4640        *UNSIGNED_INTEGER_TYPES,
4641        Type.BIT,
4642    }
4643
4644    FLOAT_TYPES = {
4645        Type.DOUBLE,
4646        Type.FLOAT,
4647    }
4648
4649    REAL_TYPES = {
4650        *FLOAT_TYPES,
4651        Type.BIGDECIMAL,
4652        Type.DECIMAL,
4653        Type.DECIMAL32,
4654        Type.DECIMAL64,
4655        Type.DECIMAL128,
4656        Type.DECIMAL256,
4657        Type.MONEY,
4658        Type.SMALLMONEY,
4659        Type.UDECIMAL,
4660        Type.UDOUBLE,
4661    }
4662
4663    NUMERIC_TYPES = {
4664        *INTEGER_TYPES,
4665        *REAL_TYPES,
4666    }
4667
4668    TEMPORAL_TYPES = {
4669        Type.DATE,
4670        Type.DATE32,
4671        Type.DATETIME,
4672        Type.DATETIME2,
4673        Type.DATETIME64,
4674        Type.SMALLDATETIME,
4675        Type.TIME,
4676        Type.TIMESTAMP,
4677        Type.TIMESTAMPNTZ,
4678        Type.TIMESTAMPLTZ,
4679        Type.TIMESTAMPTZ,
4680        Type.TIMESTAMP_MS,
4681        Type.TIMESTAMP_NS,
4682        Type.TIMESTAMP_S,
4683        Type.TIMETZ,
4684    }
4685
4686    @classmethod
4687    def build(
4688        cls,
4689        dtype: DATA_TYPE,
4690        dialect: DialectType = None,
4691        udt: bool = False,
4692        copy: bool = True,
4693        **kwargs,
4694    ) -> DataType:
4695        """
4696        Constructs a DataType object.
4697
4698        Args:
4699            dtype: the data type of interest.
4700            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4701            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4702                DataType, thus creating a user-defined type.
4703            copy: whether to copy the data type.
4704            kwargs: additional arguments to pass in the constructor of DataType.
4705
4706        Returns:
4707            The constructed DataType object.
4708        """
4709        from sqlglot import parse_one
4710
4711        if isinstance(dtype, str):
4712            if dtype.upper() == "UNKNOWN":
4713                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4714
4715            try:
4716                data_type_exp = parse_one(
4717                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4718                )
4719            except ParseError:
4720                if udt:
4721                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4722                raise
4723        elif isinstance(dtype, DataType.Type):
4724            data_type_exp = DataType(this=dtype)
4725        elif isinstance(dtype, DataType):
4726            return maybe_copy(dtype, copy)
4727        else:
4728            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4729
4730        return DataType(**{**data_type_exp.args, **kwargs})
4731
4732    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4733        """
4734        Checks whether this DataType matches one of the provided data types. Nested types or precision
4735        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4736
4737        Args:
4738            dtypes: the data types to compare this DataType to.
4739            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4740                If false, it means that NULLABLE<INT> is equivalent to INT.
4741
4742        Returns:
4743            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4744        """
4745        self_is_nullable = self.args.get("nullable")
4746        for dtype in dtypes:
4747            other_type = DataType.build(dtype, copy=False, udt=True)
4748            other_is_nullable = other_type.args.get("nullable")
4749            if (
4750                other_type.expressions
4751                or (check_nullable and (self_is_nullable or other_is_nullable))
4752                or self.this == DataType.Type.USERDEFINED
4753                or other_type.this == DataType.Type.USERDEFINED
4754            ):
4755                matches = self == other_type
4756            else:
4757                matches = self.this == other_type.this
4758
4759            if matches:
4760                return True
4761        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.LIST: 'LIST'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.UNION: 'UNION'>}
TEXT_TYPES = {<Type.NAME: 'NAME'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>}
INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT256: 'UINT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.BIT: 'BIT'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT256: 'UINT256'>, <Type.MONEY: 'MONEY'>, <Type.UINT: 'UINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT128: 'UINT128'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.BIT: 'BIT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UTINYINT: 'UTINYINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.USMALLINT: 'USMALLINT'>, <Type.FLOAT: 'FLOAT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
TEMPORAL_TYPES = {<Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE32: 'DATE32'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4686    @classmethod
4687    def build(
4688        cls,
4689        dtype: DATA_TYPE,
4690        dialect: DialectType = None,
4691        udt: bool = False,
4692        copy: bool = True,
4693        **kwargs,
4694    ) -> DataType:
4695        """
4696        Constructs a DataType object.
4697
4698        Args:
4699            dtype: the data type of interest.
4700            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4701            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4702                DataType, thus creating a user-defined type.
4703            copy: whether to copy the data type.
4704            kwargs: additional arguments to pass in the constructor of DataType.
4705
4706        Returns:
4707            The constructed DataType object.
4708        """
4709        from sqlglot import parse_one
4710
4711        if isinstance(dtype, str):
4712            if dtype.upper() == "UNKNOWN":
4713                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4714
4715            try:
4716                data_type_exp = parse_one(
4717                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4718                )
4719            except ParseError:
4720                if udt:
4721                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4722                raise
4723        elif isinstance(dtype, DataType.Type):
4724            data_type_exp = DataType(this=dtype)
4725        elif isinstance(dtype, DataType):
4726            return maybe_copy(dtype, copy)
4727        else:
4728            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4729
4730        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.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4732    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4733        """
4734        Checks whether this DataType matches one of the provided data types. Nested types or precision
4735        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4736
4737        Args:
4738            dtypes: the data types to compare this DataType to.
4739            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4740                If false, it means that NULLABLE<INT> is equivalent to INT.
4741
4742        Returns:
4743            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4744        """
4745        self_is_nullable = self.args.get("nullable")
4746        for dtype in dtypes:
4747            other_type = DataType.build(dtype, copy=False, udt=True)
4748            other_is_nullable = other_type.args.get("nullable")
4749            if (
4750                other_type.expressions
4751                or (check_nullable and (self_is_nullable or other_is_nullable))
4752                or self.this == DataType.Type.USERDEFINED
4753                or other_type.this == DataType.Type.USERDEFINED
4754            ):
4755                matches = self == other_type
4756            else:
4757                matches = self.this == other_type.this
4758
4759            if matches:
4760                return True
4761        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.
  • check_nullable: whether to take the NULLABLE type constructor into account for the comparison. If false, it means that NULLABLE is equivalent to INT.
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):
4467    class Type(AutoName):
4468        ARRAY = auto()
4469        AGGREGATEFUNCTION = auto()
4470        SIMPLEAGGREGATEFUNCTION = auto()
4471        BIGDECIMAL = auto()
4472        BIGINT = auto()
4473        BIGSERIAL = auto()
4474        BINARY = auto()
4475        BIT = auto()
4476        BLOB = auto()
4477        BOOLEAN = auto()
4478        BPCHAR = auto()
4479        CHAR = auto()
4480        DATE = auto()
4481        DATE32 = auto()
4482        DATEMULTIRANGE = auto()
4483        DATERANGE = auto()
4484        DATETIME = auto()
4485        DATETIME2 = auto()
4486        DATETIME64 = auto()
4487        DECIMAL = auto()
4488        DECIMAL32 = auto()
4489        DECIMAL64 = auto()
4490        DECIMAL128 = auto()
4491        DECIMAL256 = auto()
4492        DOUBLE = auto()
4493        DYNAMIC = auto()
4494        ENUM = auto()
4495        ENUM8 = auto()
4496        ENUM16 = auto()
4497        FIXEDSTRING = auto()
4498        FLOAT = auto()
4499        GEOGRAPHY = auto()
4500        GEOMETRY = auto()
4501        POINT = auto()
4502        RING = auto()
4503        LINESTRING = auto()
4504        MULTILINESTRING = auto()
4505        POLYGON = auto()
4506        MULTIPOLYGON = auto()
4507        HLLSKETCH = auto()
4508        HSTORE = auto()
4509        IMAGE = auto()
4510        INET = auto()
4511        INT = auto()
4512        INT128 = auto()
4513        INT256 = auto()
4514        INT4MULTIRANGE = auto()
4515        INT4RANGE = auto()
4516        INT8MULTIRANGE = auto()
4517        INT8RANGE = auto()
4518        INTERVAL = auto()
4519        IPADDRESS = auto()
4520        IPPREFIX = auto()
4521        IPV4 = auto()
4522        IPV6 = auto()
4523        JSON = auto()
4524        JSONB = auto()
4525        LIST = auto()
4526        LONGBLOB = auto()
4527        LONGTEXT = auto()
4528        LOWCARDINALITY = auto()
4529        MAP = auto()
4530        MEDIUMBLOB = auto()
4531        MEDIUMINT = auto()
4532        MEDIUMTEXT = auto()
4533        MONEY = auto()
4534        NAME = auto()
4535        NCHAR = auto()
4536        NESTED = auto()
4537        NOTHING = auto()
4538        NULL = auto()
4539        NUMMULTIRANGE = auto()
4540        NUMRANGE = auto()
4541        NVARCHAR = auto()
4542        OBJECT = auto()
4543        RANGE = auto()
4544        ROWVERSION = auto()
4545        SERIAL = auto()
4546        SET = auto()
4547        SMALLDATETIME = auto()
4548        SMALLINT = auto()
4549        SMALLMONEY = auto()
4550        SMALLSERIAL = auto()
4551        STRUCT = auto()
4552        SUPER = auto()
4553        TEXT = auto()
4554        TINYBLOB = auto()
4555        TINYTEXT = auto()
4556        TIME = auto()
4557        TIMETZ = auto()
4558        TIMESTAMP = auto()
4559        TIMESTAMPNTZ = auto()
4560        TIMESTAMPLTZ = auto()
4561        TIMESTAMPTZ = auto()
4562        TIMESTAMP_S = auto()
4563        TIMESTAMP_MS = auto()
4564        TIMESTAMP_NS = auto()
4565        TINYINT = auto()
4566        TSMULTIRANGE = auto()
4567        TSRANGE = auto()
4568        TSTZMULTIRANGE = auto()
4569        TSTZRANGE = auto()
4570        UBIGINT = auto()
4571        UINT = auto()
4572        UINT128 = auto()
4573        UINT256 = auto()
4574        UMEDIUMINT = auto()
4575        UDECIMAL = auto()
4576        UDOUBLE = auto()
4577        UNION = auto()
4578        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4579        USERDEFINED = "USER-DEFINED"
4580        USMALLINT = auto()
4581        UTINYINT = auto()
4582        UUID = auto()
4583        VARBINARY = auto()
4584        VARCHAR = auto()
4585        VARIANT = auto()
4586        VECTOR = auto()
4587        XML = auto()
4588        YEAR = auto()
4589        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BLOB = <Type.BLOB: 'BLOB'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME2 = <Type.DATETIME2: 'DATETIME2'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
DYNAMIC = <Type.DYNAMIC: 'DYNAMIC'>
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'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
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'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
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'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NOTHING = <Type.NOTHING: 'NOTHING'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
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'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
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'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
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'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4768class PseudoType(DataType):
4769    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4773class ObjectIdentifier(DataType):
4774    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4778class SubqueryPredicate(Predicate):
4779    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4782class All(SubqueryPredicate):
4783    pass
key = 'all'
class Any(SubqueryPredicate):
4786class Any(SubqueryPredicate):
4787    pass
key = 'any'
class Command(Expression):
4792class Command(Expression):
4793    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4796class Transaction(Expression):
4797    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4800class Commit(Expression):
4801    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4804class Rollback(Expression):
4805    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4808class Alter(Expression):
4809    arg_types = {
4810        "this": True,
4811        "kind": True,
4812        "actions": True,
4813        "exists": False,
4814        "only": False,
4815        "options": False,
4816        "cluster": False,
4817        "not_valid": False,
4818    }
4819
4820    @property
4821    def kind(self) -> t.Optional[str]:
4822        kind = self.args.get("kind")
4823        return kind and kind.upper()
4824
4825    @property
4826    def actions(self) -> t.List[Expression]:
4827        return self.args.get("actions") or []
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False}
kind: Optional[str]
4820    @property
4821    def kind(self) -> t.Optional[str]:
4822        kind = self.args.get("kind")
4823        return kind and kind.upper()
actions: List[Expression]
4825    @property
4826    def actions(self) -> t.List[Expression]:
4827        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4830class Analyze(Expression):
4831    arg_types = {
4832        "kind": False,
4833        "this": False,
4834        "options": False,
4835        "mode": False,
4836        "partition": False,
4837        "expression": False,
4838        "properties": False,
4839    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4842class AnalyzeStatistics(Expression):
4843    arg_types = {
4844        "kind": True,
4845        "option": False,
4846        "this": False,
4847        "expressions": False,
4848    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4851class AnalyzeHistogram(Expression):
4852    arg_types = {
4853        "this": True,
4854        "expressions": True,
4855        "expression": False,
4856        "update_options": False,
4857    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4860class AnalyzeSample(Expression):
4861    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4864class AnalyzeListChainedRows(Expression):
4865    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4868class AnalyzeDelete(Expression):
4869    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4872class AnalyzeWith(Expression):
4873    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4876class AnalyzeValidate(Expression):
4877    arg_types = {
4878        "kind": True,
4879        "this": False,
4880        "expression": False,
4881    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4884class AnalyzeColumns(Expression):
4885    pass
key = 'analyzecolumns'
class UsingData(Expression):
4888class UsingData(Expression):
4889    pass
key = 'usingdata'
class AddConstraint(Expression):
4892class AddConstraint(Expression):
4893    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4896class AttachOption(Expression):
4897    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4900class DropPartition(Expression):
4901    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4905class ReplacePartition(Expression):
4906    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4910class Binary(Condition):
4911    arg_types = {"this": True, "expression": True}
4912
4913    @property
4914    def left(self) -> Expression:
4915        return self.this
4916
4917    @property
4918    def right(self) -> Expression:
4919        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4913    @property
4914    def left(self) -> Expression:
4915        return self.this
right: Expression
4917    @property
4918    def right(self) -> Expression:
4919        return self.expression
key = 'binary'
class Add(Binary):
4922class Add(Binary):
4923    pass
key = 'add'
class Connector(Binary):
4926class Connector(Binary):
4927    pass
key = 'connector'
class BitwiseAnd(Binary):
4930class BitwiseAnd(Binary):
4931    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4934class BitwiseLeftShift(Binary):
4935    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4938class BitwiseOr(Binary):
4939    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4942class BitwiseRightShift(Binary):
4943    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4946class BitwiseXor(Binary):
4947    pass
key = 'bitwisexor'
class Div(Binary):
4950class Div(Binary):
4951    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):
4954class Overlaps(Binary):
4955    pass
key = 'overlaps'
class Dot(Binary):
4958class Dot(Binary):
4959    @property
4960    def is_star(self) -> bool:
4961        return self.expression.is_star
4962
4963    @property
4964    def name(self) -> str:
4965        return self.expression.name
4966
4967    @property
4968    def output_name(self) -> str:
4969        return self.name
4970
4971    @classmethod
4972    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4973        """Build a Dot object with a sequence of expressions."""
4974        if len(expressions) < 2:
4975            raise ValueError("Dot requires >= 2 expressions.")
4976
4977        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4978
4979    @property
4980    def parts(self) -> t.List[Expression]:
4981        """Return the parts of a table / column in order catalog, db, table."""
4982        this, *parts = self.flatten()
4983
4984        parts.reverse()
4985
4986        for arg in COLUMN_PARTS:
4987            part = this.args.get(arg)
4988
4989            if isinstance(part, Expression):
4990                parts.append(part)
4991
4992        parts.reverse()
4993        return parts
is_star: bool
4959    @property
4960    def is_star(self) -> bool:
4961        return self.expression.is_star

Checks whether an expression is a star.

name: str
4963    @property
4964    def name(self) -> str:
4965        return self.expression.name
output_name: str
4967    @property
4968    def output_name(self) -> str:
4969        return self.name

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:
4971    @classmethod
4972    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4973        """Build a Dot object with a sequence of expressions."""
4974        if len(expressions) < 2:
4975            raise ValueError("Dot requires >= 2 expressions.")
4976
4977        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
4979    @property
4980    def parts(self) -> t.List[Expression]:
4981        """Return the parts of a table / column in order catalog, db, table."""
4982        this, *parts = self.flatten()
4983
4984        parts.reverse()
4985
4986        for arg in COLUMN_PARTS:
4987            part = this.args.get(arg)
4988
4989            if isinstance(part, Expression):
4990                parts.append(part)
4991
4992        parts.reverse()
4993        return parts

Return the parts of a table / column in order catalog, db, table.

key = 'dot'
class DPipe(Binary):
4996class DPipe(Binary):
4997    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5000class EQ(Binary, Predicate):
5001    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5004class NullSafeEQ(Binary, Predicate):
5005    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5008class NullSafeNEQ(Binary, Predicate):
5009    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5013class PropertyEQ(Binary):
5014    pass
key = 'propertyeq'
class Distance(Binary):
5017class Distance(Binary):
5018    pass
key = 'distance'
class Escape(Binary):
5021class Escape(Binary):
5022    pass
key = 'escape'
class Glob(Binary, Predicate):
5025class Glob(Binary, Predicate):
5026    pass
key = 'glob'
class GT(Binary, Predicate):
5029class GT(Binary, Predicate):
5030    pass
key = 'gt'
class GTE(Binary, Predicate):
5033class GTE(Binary, Predicate):
5034    pass
key = 'gte'
class ILike(Binary, Predicate):
5037class ILike(Binary, Predicate):
5038    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5041class ILikeAny(Binary, Predicate):
5042    pass
key = 'ilikeany'
class IntDiv(Binary):
5045class IntDiv(Binary):
5046    pass
key = 'intdiv'
class Is(Binary, Predicate):
5049class Is(Binary, Predicate):
5050    pass
key = 'is'
class Kwarg(Binary):
5053class Kwarg(Binary):
5054    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5057class Like(Binary, Predicate):
5058    pass
key = 'like'
class LikeAny(Binary, Predicate):
5061class LikeAny(Binary, Predicate):
5062    pass
key = 'likeany'
class LT(Binary, Predicate):
5065class LT(Binary, Predicate):
5066    pass
key = 'lt'
class LTE(Binary, Predicate):
5069class LTE(Binary, Predicate):
5070    pass
key = 'lte'
class Mod(Binary):
5073class Mod(Binary):
5074    pass
key = 'mod'
class Mul(Binary):
5077class Mul(Binary):
5078    pass
key = 'mul'
class NEQ(Binary, Predicate):
5081class NEQ(Binary, Predicate):
5082    pass
key = 'neq'
class Operator(Binary):
5086class Operator(Binary):
5087    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5090class SimilarTo(Binary, Predicate):
5091    pass
key = 'similarto'
class Slice(Binary):
5094class Slice(Binary):
5095    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5098class Sub(Binary):
5099    pass
key = 'sub'
class Unary(Condition):
5104class Unary(Condition):
5105    pass
key = 'unary'
class BitwiseNot(Unary):
5108class BitwiseNot(Unary):
5109    pass
key = 'bitwisenot'
class Not(Unary):
5112class Not(Unary):
5113    pass
key = 'not'
class Paren(Unary):
5116class Paren(Unary):
5117    @property
5118    def output_name(self) -> str:
5119        return self.this.name
output_name: str
5117    @property
5118    def output_name(self) -> str:
5119        return self.this.name

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):
5122class Neg(Unary):
5123    def to_py(self) -> int | Decimal:
5124        if self.is_number:
5125            return self.this.to_py() * -1
5126        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5123    def to_py(self) -> int | Decimal:
5124        if self.is_number:
5125            return self.this.to_py() * -1
5126        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5129class Alias(Expression):
5130    arg_types = {"this": True, "alias": False}
5131
5132    @property
5133    def output_name(self) -> str:
5134        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5132    @property
5133    def output_name(self) -> str:
5134        return self.alias

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 PivotAlias(Alias):
5139class PivotAlias(Alias):
5140    pass
key = 'pivotalias'
class PivotAny(Expression):
5145class PivotAny(Expression):
5146    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5149class Aliases(Expression):
5150    arg_types = {"this": True, "expressions": True}
5151
5152    @property
5153    def aliases(self):
5154        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5152    @property
5153    def aliases(self):
5154        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5158class AtIndex(Expression):
5159    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5162class AtTimeZone(Expression):
5163    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5166class FromTimeZone(Expression):
5167    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5170class Between(Predicate):
5171    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5174class Bracket(Condition):
5175    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5176    arg_types = {
5177        "this": True,
5178        "expressions": True,
5179        "offset": False,
5180        "safe": False,
5181        "returns_list_for_maps": False,
5182    }
5183
5184    @property
5185    def output_name(self) -> str:
5186        if len(self.expressions) == 1:
5187            return self.expressions[0].output_name
5188
5189        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5184    @property
5185    def output_name(self) -> str:
5186        if len(self.expressions) == 1:
5187            return self.expressions[0].output_name
5188
5189        return super().output_name

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 Distinct(Expression):
5192class Distinct(Expression):
5193    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5196class In(Predicate):
5197    arg_types = {
5198        "this": True,
5199        "expressions": False,
5200        "query": False,
5201        "unnest": False,
5202        "field": False,
5203        "is_global": False,
5204    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5208class ForIn(Expression):
5209    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5212class TimeUnit(Expression):
5213    """Automatically converts unit arg into a var."""
5214
5215    arg_types = {"unit": False}
5216
5217    UNABBREVIATED_UNIT_NAME = {
5218        "D": "DAY",
5219        "H": "HOUR",
5220        "M": "MINUTE",
5221        "MS": "MILLISECOND",
5222        "NS": "NANOSECOND",
5223        "Q": "QUARTER",
5224        "S": "SECOND",
5225        "US": "MICROSECOND",
5226        "W": "WEEK",
5227        "Y": "YEAR",
5228    }
5229
5230    VAR_LIKE = (Column, Literal, Var)
5231
5232    def __init__(self, **args):
5233        unit = args.get("unit")
5234        if isinstance(unit, self.VAR_LIKE):
5235            args["unit"] = Var(
5236                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5237            )
5238        elif isinstance(unit, Week):
5239            unit.set("this", Var(this=unit.this.name.upper()))
5240
5241        super().__init__(**args)
5242
5243    @property
5244    def unit(self) -> t.Optional[Var | IntervalSpan]:
5245        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5232    def __init__(self, **args):
5233        unit = args.get("unit")
5234        if isinstance(unit, self.VAR_LIKE):
5235            args["unit"] = Var(
5236                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5237            )
5238        elif isinstance(unit, Week):
5239            unit.set("this", Var(this=unit.this.name.upper()))
5240
5241        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: Union[Var, IntervalSpan, NoneType]
5243    @property
5244    def unit(self) -> t.Optional[Var | IntervalSpan]:
5245        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5248class IntervalOp(TimeUnit):
5249    arg_types = {"unit": False, "expression": True}
5250
5251    def interval(self):
5252        return Interval(
5253            this=self.expression.copy(),
5254            unit=self.unit.copy() if self.unit else None,
5255        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5251    def interval(self):
5252        return Interval(
5253            this=self.expression.copy(),
5254            unit=self.unit.copy() if self.unit else None,
5255        )
key = 'intervalop'
class IntervalSpan(DataType):
5261class IntervalSpan(DataType):
5262    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5265class Interval(TimeUnit):
5266    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5269class IgnoreNulls(Expression):
5270    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5273class RespectNulls(Expression):
5274    pass
key = 'respectnulls'
class HavingMax(Expression):
5278class HavingMax(Expression):
5279    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5283class Func(Condition):
5284    """
5285    The base class for all function expressions.
5286
5287    Attributes:
5288        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5289            treated as a variable length argument and the argument's value will be stored as a list.
5290        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5291            function expression. These values are used to map this node to a name during parsing as
5292            well as to provide the function's name during SQL string generation. By default the SQL
5293            name is set to the expression's class name transformed to snake case.
5294    """
5295
5296    is_var_len_args = False
5297
5298    @classmethod
5299    def from_arg_list(cls, args):
5300        if cls.is_var_len_args:
5301            all_arg_keys = list(cls.arg_types)
5302            # If this function supports variable length argument treat the last argument as such.
5303            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5304            num_non_var = len(non_var_len_arg_keys)
5305
5306            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5307            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5308        else:
5309            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5310
5311        return cls(**args_dict)
5312
5313    @classmethod
5314    def sql_names(cls):
5315        if cls is Func:
5316            raise NotImplementedError(
5317                "SQL name is only supported by concrete function implementations"
5318            )
5319        if "_sql_names" not in cls.__dict__:
5320            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5321        return cls._sql_names
5322
5323    @classmethod
5324    def sql_name(cls):
5325        return cls.sql_names()[0]
5326
5327    @classmethod
5328    def default_parser_mappings(cls):
5329        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): 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):
5298    @classmethod
5299    def from_arg_list(cls, args):
5300        if cls.is_var_len_args:
5301            all_arg_keys = list(cls.arg_types)
5302            # If this function supports variable length argument treat the last argument as such.
5303            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5304            num_non_var = len(non_var_len_arg_keys)
5305
5306            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5307            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5308        else:
5309            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5310
5311        return cls(**args_dict)
@classmethod
def sql_names(cls):
5313    @classmethod
5314    def sql_names(cls):
5315        if cls is Func:
5316            raise NotImplementedError(
5317                "SQL name is only supported by concrete function implementations"
5318            )
5319        if "_sql_names" not in cls.__dict__:
5320            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5321        return cls._sql_names
@classmethod
def sql_name(cls):
5323    @classmethod
5324    def sql_name(cls):
5325        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5327    @classmethod
5328    def default_parser_mappings(cls):
5329        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5332class AggFunc(Func):
5333    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5336class ParameterizedAgg(AggFunc):
5337    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5340class Abs(Func):
5341    pass
key = 'abs'
class ArgMax(AggFunc):
5344class ArgMax(AggFunc):
5345    arg_types = {"this": True, "expression": True, "count": False}
5346    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5349class ArgMin(AggFunc):
5350    arg_types = {"this": True, "expression": True, "count": False}
5351    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5354class ApproxTopK(AggFunc):
5355    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5358class Flatten(Func):
5359    pass
key = 'flatten'
class Transform(Func):
5363class Transform(Func):
5364    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5367class Anonymous(Func):
5368    arg_types = {"this": True, "expressions": False}
5369    is_var_len_args = True
5370
5371    @property
5372    def name(self) -> str:
5373        return self.this if isinstance(self.this, str) else self.this.name
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
5371    @property
5372    def name(self) -> str:
5373        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5376class AnonymousAggFunc(AggFunc):
5377    arg_types = {"this": True, "expressions": False}
5378    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5382class CombinedAggFunc(AnonymousAggFunc):
5383    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5386class CombinedParameterizedAgg(ParameterizedAgg):
5387    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5392class Hll(AggFunc):
5393    arg_types = {"this": True, "expressions": False}
5394    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5397class ApproxDistinct(AggFunc):
5398    arg_types = {"this": True, "accuracy": False}
5399    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5402class Apply(Func):
5403    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5406class Array(Func):
5407    arg_types = {"expressions": False, "bracket_notation": False}
5408    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5412class ToArray(Func):
5413    pass
key = 'toarray'
class List(Func):
5417class List(Func):
5418    arg_types = {"expressions": False}
5419    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5423class Pad(Func):
5424    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
arg_types = {'this': True, 'expression': True, 'fill_pattern': False, 'is_left': True}
key = 'pad'
class ToChar(Func):
5429class ToChar(Func):
5430    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5435class ToNumber(Func):
5436    arg_types = {
5437        "this": True,
5438        "format": False,
5439        "nlsparam": False,
5440        "precision": False,
5441        "scale": False,
5442    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5446class ToDouble(Func):
5447    arg_types = {
5448        "this": True,
5449        "format": False,
5450    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5453class Columns(Func):
5454    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5458class Convert(Func):
5459    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5462class ConvertTimezone(Func):
5463    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
5466class GenerateSeries(Func):
5467    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ExplodingGenerateSeries(GenerateSeries):
5473class ExplodingGenerateSeries(GenerateSeries):
5474    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5477class ArrayAgg(AggFunc):
5478    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5481class ArrayUniqueAgg(AggFunc):
5482    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5485class ArrayAll(Func):
5486    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5490class ArrayAny(Func):
5491    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5494class ArrayConcat(Func):
5495    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5496    arg_types = {"this": True, "expressions": False}
5497    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5500class ArrayConstructCompact(Func):
5501    arg_types = {"expressions": True}
5502    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5505class ArrayContains(Binary, Func):
5506    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5509class ArrayContainsAll(Binary, Func):
5510    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5513class ArrayFilter(Func):
5514    arg_types = {"this": True, "expression": True}
5515    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5518class ArrayToString(Func):
5519    arg_types = {"this": True, "expression": True, "null": False}
5520    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5524class String(Func):
5525    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5528class StringToArray(Func):
5529    arg_types = {"this": True, "expression": True, "null": False}
5530    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5533class ArrayOverlaps(Binary, Func):
5534    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5537class ArraySize(Func):
5538    arg_types = {"this": True, "expression": False}
5539    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5542class ArraySort(Func):
5543    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5546class ArraySum(Func):
5547    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5550class ArrayUnionAgg(AggFunc):
5551    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5554class Avg(AggFunc):
5555    pass
key = 'avg'
class AnyValue(AggFunc):
5558class AnyValue(AggFunc):
5559    pass
key = 'anyvalue'
class Lag(AggFunc):
5562class Lag(AggFunc):
5563    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5566class Lead(AggFunc):
5567    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5572class First(AggFunc):
5573    pass
key = 'first'
class Last(AggFunc):
5576class Last(AggFunc):
5577    pass
key = 'last'
class FirstValue(AggFunc):
5580class FirstValue(AggFunc):
5581    pass
key = 'firstvalue'
class LastValue(AggFunc):
5584class LastValue(AggFunc):
5585    pass
key = 'lastvalue'
class NthValue(AggFunc):
5588class NthValue(AggFunc):
5589    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5592class Case(Func):
5593    arg_types = {"this": False, "ifs": True, "default": False}
5594
5595    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5596        instance = maybe_copy(self, copy)
5597        instance.append(
5598            "ifs",
5599            If(
5600                this=maybe_parse(condition, copy=copy, **opts),
5601                true=maybe_parse(then, copy=copy, **opts),
5602            ),
5603        )
5604        return instance
5605
5606    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5607        instance = maybe_copy(self, copy)
5608        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5609        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:
5595    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5596        instance = maybe_copy(self, copy)
5597        instance.append(
5598            "ifs",
5599            If(
5600                this=maybe_parse(condition, copy=copy, **opts),
5601                true=maybe_parse(then, copy=copy, **opts),
5602            ),
5603        )
5604        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5606    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5607        instance = maybe_copy(self, copy)
5608        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5609        return instance
key = 'case'
class Cast(Func):
5612class Cast(Func):
5613    arg_types = {
5614        "this": True,
5615        "to": True,
5616        "format": False,
5617        "safe": False,
5618        "action": False,
5619        "default": False,
5620    }
5621
5622    @property
5623    def name(self) -> str:
5624        return self.this.name
5625
5626    @property
5627    def to(self) -> DataType:
5628        return self.args["to"]
5629
5630    @property
5631    def output_name(self) -> str:
5632        return self.name
5633
5634    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5635        """
5636        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5637        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5638        array<int> != array<float>.
5639
5640        Args:
5641            dtypes: the data types to compare this Cast's DataType to.
5642
5643        Returns:
5644            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5645        """
5646        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5622    @property
5623    def name(self) -> str:
5624        return self.this.name
to: DataType
5626    @property
5627    def to(self) -> DataType:
5628        return self.args["to"]
output_name: str
5630    @property
5631    def output_name(self) -> str:
5632        return self.name

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:
5634    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5635        """
5636        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5637        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5638        array<int> != array<float>.
5639
5640        Args:
5641            dtypes: the data types to compare this Cast's DataType to.
5642
5643        Returns:
5644            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5645        """
5646        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):
5649class TryCast(Cast):
5650    pass
key = 'trycast'
class JSONCast(Cast):
5654class JSONCast(Cast):
5655    pass
key = 'jsoncast'
class Try(Func):
5658class Try(Func):
5659    pass
key = 'try'
class CastToStrType(Func):
5662class CastToStrType(Func):
5663    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5666class Collate(Binary, Func):
5667    pass
key = 'collate'
class Ceil(Func):
5670class Ceil(Func):
5671    arg_types = {"this": True, "decimals": False, "to": False}
5672    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5675class Coalesce(Func):
5676    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5677    is_var_len_args = True
5678    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5681class Chr(Func):
5682    arg_types = {"expressions": True, "charset": False}
5683    is_var_len_args = True
5684    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5687class Concat(Func):
5688    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5689    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5692class ConcatWs(Concat):
5693    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5696class Contains(Func):
5697    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5701class ConnectByRoot(Func):
5702    pass
key = 'connectbyroot'
class Count(AggFunc):
5705class Count(AggFunc):
5706    arg_types = {"this": False, "expressions": False, "big_int": False}
5707    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5710class CountIf(AggFunc):
5711    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5715class Cbrt(Func):
5716    pass
key = 'cbrt'
class CurrentDate(Func):
5719class CurrentDate(Func):
5720    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5723class CurrentDatetime(Func):
5724    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5727class CurrentTime(Func):
5728    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5731class CurrentTimestamp(Func):
5732    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5735class CurrentSchema(Func):
5736    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5739class CurrentUser(Func):
5740    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5743class DateAdd(Func, IntervalOp):
5744    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5747class DateBin(Func, IntervalOp):
5748    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
5751class DateSub(Func, IntervalOp):
5752    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5755class DateDiff(Func, TimeUnit):
5756    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5757    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datediff'
class DateTrunc(Func):
5760class DateTrunc(Func):
5761    arg_types = {"unit": True, "this": True, "zone": False}
5762
5763    def __init__(self, **args):
5764        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5765        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5766        unabbreviate = args.pop("unabbreviate", True)
5767
5768        unit = args.get("unit")
5769        if isinstance(unit, TimeUnit.VAR_LIKE):
5770            unit_name = unit.name.upper()
5771            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5772                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5773
5774            args["unit"] = Literal.string(unit_name)
5775        elif isinstance(unit, Week):
5776            unit.set("this", Literal.string(unit.this.name.upper()))
5777
5778        super().__init__(**args)
5779
5780    @property
5781    def unit(self) -> Expression:
5782        return self.args["unit"]
DateTrunc(**args)
5763    def __init__(self, **args):
5764        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5765        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5766        unabbreviate = args.pop("unabbreviate", True)
5767
5768        unit = args.get("unit")
5769        if isinstance(unit, TimeUnit.VAR_LIKE):
5770            unit_name = unit.name.upper()
5771            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5772                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5773
5774            args["unit"] = Literal.string(unit_name)
5775        elif isinstance(unit, Week):
5776            unit.set("this", Literal.string(unit.this.name.upper()))
5777
5778        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5780    @property
5781    def unit(self) -> Expression:
5782        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5787class Datetime(Func):
5788    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5791class DatetimeAdd(Func, IntervalOp):
5792    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5795class DatetimeSub(Func, IntervalOp):
5796    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5799class DatetimeDiff(Func, TimeUnit):
5800    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5803class DatetimeTrunc(Func, TimeUnit):
5804    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5807class DayOfWeek(Func):
5808    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5813class DayOfWeekIso(Func):
5814    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5817class DayOfMonth(Func):
5818    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5821class DayOfYear(Func):
5822    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5825class ToDays(Func):
5826    pass
key = 'todays'
class WeekOfYear(Func):
5829class WeekOfYear(Func):
5830    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5833class MonthsBetween(Func):
5834    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5837class MakeInterval(Func):
5838    arg_types = {
5839        "year": False,
5840        "month": False,
5841        "day": False,
5842        "hour": False,
5843        "minute": False,
5844        "second": False,
5845    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5848class LastDay(Func, TimeUnit):
5849    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5850    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5853class Extract(Func):
5854    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5857class Exists(Func, SubqueryPredicate):
5858    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5861class Timestamp(Func):
5862    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5865class TimestampAdd(Func, TimeUnit):
5866    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5869class TimestampSub(Func, TimeUnit):
5870    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5873class TimestampDiff(Func, TimeUnit):
5874    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5875    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5878class TimestampTrunc(Func, TimeUnit):
5879    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5882class TimeAdd(Func, TimeUnit):
5883    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5886class TimeSub(Func, TimeUnit):
5887    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5890class TimeDiff(Func, TimeUnit):
5891    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5894class TimeTrunc(Func, TimeUnit):
5895    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5898class DateFromParts(Func):
5899    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5900    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5903class TimeFromParts(Func):
5904    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5905    arg_types = {
5906        "hour": True,
5907        "min": True,
5908        "sec": True,
5909        "nano": False,
5910        "fractions": False,
5911        "precision": False,
5912    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5915class DateStrToDate(Func):
5916    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5919class DateToDateStr(Func):
5920    pass
key = 'datetodatestr'
class DateToDi(Func):
5923class DateToDi(Func):
5924    pass
key = 'datetodi'
class Date(Func):
5928class Date(Func):
5929    arg_types = {"this": False, "zone": False, "expressions": False}
5930    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5933class Day(Func):
5934    pass
key = 'day'
class Decode(Func):
5937class Decode(Func):
5938    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5941class DiToDate(Func):
5942    pass
key = 'ditodate'
class Encode(Func):
5945class Encode(Func):
5946    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5949class Exp(Func):
5950    pass
key = 'exp'
class Explode(Func, UDTF):
5954class Explode(Func, UDTF):
5955    arg_types = {"this": True, "expressions": False}
5956    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5960class Inline(Func):
5961    pass
key = 'inline'
class ExplodeOuter(Explode):
5964class ExplodeOuter(Explode):
5965    pass
key = 'explodeouter'
class Posexplode(Explode):
5968class Posexplode(Explode):
5969    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5972class PosexplodeOuter(Posexplode, ExplodeOuter):
5973    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5976class Unnest(Func, UDTF):
5977    arg_types = {
5978        "expressions": True,
5979        "alias": False,
5980        "offset": False,
5981        "explode_array": False,
5982    }
5983
5984    @property
5985    def selects(self) -> t.List[Expression]:
5986        columns = super().selects
5987        offset = self.args.get("offset")
5988        if offset:
5989            columns = columns + [to_identifier("offset") if offset is True else offset]
5990        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5984    @property
5985    def selects(self) -> t.List[Expression]:
5986        columns = super().selects
5987        offset = self.args.get("offset")
5988        if offset:
5989            columns = columns + [to_identifier("offset") if offset is True else offset]
5990        return columns
key = 'unnest'
class Floor(Func):
5993class Floor(Func):
5994    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5997class FromBase64(Func):
5998    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6001class FeaturesAtTime(Func):
6002    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
arg_types = {'this': True, 'time': False, 'num_rows': False, 'ignore_feature_nulls': False}
key = 'featuresattime'
class ToBase64(Func):
6005class ToBase64(Func):
6006    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6010class FromISO8601Timestamp(Func):
6011    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6014class GapFill(Func):
6015    arg_types = {
6016        "this": True,
6017        "ts_column": True,
6018        "bucket_width": True,
6019        "partitioning_columns": False,
6020        "value_columns": False,
6021        "origin": False,
6022        "ignore_nulls": False,
6023    }
arg_types = {'this': True, 'ts_column': True, 'bucket_width': True, 'partitioning_columns': False, 'value_columns': False, 'origin': False, 'ignore_nulls': False}
key = 'gapfill'
class GenerateDateArray(Func):
6027class GenerateDateArray(Func):
6028    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6032class GenerateTimestampArray(Func):
6033    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6036class Greatest(Func):
6037    arg_types = {"this": True, "expressions": False}
6038    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6043class OverflowTruncateBehavior(Expression):
6044    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6047class GroupConcat(AggFunc):
6048    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6051class Hex(Func):
6052    pass
key = 'hex'
class LowerHex(Hex):
6055class LowerHex(Hex):
6056    pass
key = 'lowerhex'
class And(Connector, Func):
6059class And(Connector, Func):
6060    pass
key = 'and'
class Or(Connector, Func):
6063class Or(Connector, Func):
6064    pass
key = 'or'
class Xor(Connector, Func):
6067class Xor(Connector, Func):
6068    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6071class If(Func):
6072    arg_types = {"this": True, "true": True, "false": False}
6073    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6076class Nullif(Func):
6077    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6080class Initcap(Func):
6081    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6084class IsAscii(Func):
6085    pass
key = 'isascii'
class IsNan(Func):
6088class IsNan(Func):
6089    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6093class Int64(Func):
6094    pass
key = 'int64'
class IsInf(Func):
6097class IsInf(Func):
6098    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6102class JSON(Expression):
6103    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6106class JSONPath(Expression):
6107    arg_types = {"expressions": True, "escape": False}
6108
6109    @property
6110    def output_name(self) -> str:
6111        last_segment = self.expressions[-1].this
6112        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6109    @property
6110    def output_name(self) -> str:
6111        last_segment = self.expressions[-1].this
6112        return last_segment if isinstance(last_segment, str) else ""

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 = 'jsonpath'
class JSONPathPart(Expression):
6115class JSONPathPart(Expression):
6116    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6119class JSONPathFilter(JSONPathPart):
6120    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6123class JSONPathKey(JSONPathPart):
6124    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6127class JSONPathRecursive(JSONPathPart):
6128    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6131class JSONPathRoot(JSONPathPart):
6132    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6135class JSONPathScript(JSONPathPart):
6136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6139class JSONPathSlice(JSONPathPart):
6140    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6143class JSONPathSelector(JSONPathPart):
6144    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6147class JSONPathSubscript(JSONPathPart):
6148    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6151class JSONPathUnion(JSONPathPart):
6152    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6155class JSONPathWildcard(JSONPathPart):
6156    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6159class FormatJson(Expression):
6160    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6163class JSONKeyValue(Expression):
6164    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6167class JSONObject(Func):
6168    arg_types = {
6169        "expressions": False,
6170        "null_handling": False,
6171        "unique_keys": False,
6172        "return_type": False,
6173        "encoding": False,
6174    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6177class JSONObjectAgg(AggFunc):
6178    arg_types = {
6179        "expressions": False,
6180        "null_handling": False,
6181        "unique_keys": False,
6182        "return_type": False,
6183        "encoding": False,
6184    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6188class JSONBObjectAgg(AggFunc):
6189    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6193class JSONArray(Func):
6194    arg_types = {
6195        "expressions": True,
6196        "null_handling": False,
6197        "return_type": False,
6198        "strict": False,
6199    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6203class JSONArrayAgg(Func):
6204    arg_types = {
6205        "this": True,
6206        "order": False,
6207        "null_handling": False,
6208        "return_type": False,
6209        "strict": False,
6210    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6213class JSONExists(Func):
6214    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
arg_types = {'this': True, 'path': True, 'passing': False, 'on_condition': False}
key = 'jsonexists'
class JSONColumnDef(Expression):
6219class JSONColumnDef(Expression):
6220    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):
6223class JSONSchema(Expression):
6224    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6228class JSONValue(Expression):
6229    arg_types = {
6230        "this": True,
6231        "path": True,
6232        "returning": False,
6233        "on_condition": False,
6234    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6237class JSONValueArray(Func):
6238    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6242class JSONTable(Func):
6243    arg_types = {
6244        "this": True,
6245        "schema": True,
6246        "path": False,
6247        "error_handling": False,
6248        "empty_handling": False,
6249    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6253class ObjectInsert(Func):
6254    arg_types = {
6255        "this": True,
6256        "key": True,
6257        "value": True,
6258        "update_flag": False,
6259    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6262class OpenJSONColumnDef(Expression):
6263    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):
6266class OpenJSON(Func):
6267    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6270class JSONBContains(Binary, Func):
6271    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6274class JSONBExists(Func):
6275    arg_types = {"this": True, "path": True}
6276    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6279class JSONExtract(Binary, Func):
6280    arg_types = {
6281        "this": True,
6282        "expression": True,
6283        "only_json_types": False,
6284        "expressions": False,
6285        "variant_extract": False,
6286        "json_query": False,
6287        "option": False,
6288        "quote": False,
6289        "on_condition": False,
6290    }
6291    _sql_names = ["JSON_EXTRACT"]
6292    is_var_len_args = True
6293
6294    @property
6295    def output_name(self) -> str:
6296        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False, 'json_query': False, 'option': False, 'quote': False, 'on_condition': False}
is_var_len_args = True
output_name: str
6294    @property
6295    def output_name(self) -> str:
6296        return self.expression.output_name if not self.expressions else ""

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 = 'jsonextract'
class JSONExtractQuote(Expression):
6300class JSONExtractQuote(Expression):
6301    arg_types = {
6302        "option": True,
6303        "scalar": False,
6304    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6307class JSONExtractArray(Func):
6308    arg_types = {"this": True, "expression": False}
6309    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6312class JSONExtractScalar(Binary, Func):
6313    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6314    _sql_names = ["JSON_EXTRACT_SCALAR"]
6315    is_var_len_args = True
6316
6317    @property
6318    def output_name(self) -> str:
6319        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
6317    @property
6318    def output_name(self) -> str:
6319        return self.expression.output_name

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 = 'jsonextractscalar'
class JSONBExtract(Binary, Func):
6322class JSONBExtract(Binary, Func):
6323    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6326class JSONBExtractScalar(Binary, Func):
6327    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6330class JSONFormat(Func):
6331    arg_types = {"this": False, "options": False, "is_json": False}
6332    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6336class JSONArrayContains(Binary, Predicate, Func):
6337    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6340class ParseJSON(Func):
6341    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6342    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6343    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6344    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6347class Least(Func):
6348    arg_types = {"this": True, "expressions": False}
6349    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6352class Left(Func):
6353    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6360class Length(Func):
6361    arg_types = {"this": True, "binary": False, "encoding": False}
6362    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6365class Levenshtein(Func):
6366    arg_types = {
6367        "this": True,
6368        "expression": False,
6369        "ins_cost": False,
6370        "del_cost": False,
6371        "sub_cost": False,
6372        "max_dist": False,
6373    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6376class Ln(Func):
6377    pass
key = 'ln'
class Log(Func):
6380class Log(Func):
6381    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6384class LogicalOr(AggFunc):
6385    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6388class LogicalAnd(AggFunc):
6389    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6392class Lower(Func):
6393    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6396class Map(Func):
6397    arg_types = {"keys": False, "values": False}
6398
6399    @property
6400    def keys(self) -> t.List[Expression]:
6401        keys = self.args.get("keys")
6402        return keys.expressions if keys else []
6403
6404    @property
6405    def values(self) -> t.List[Expression]:
6406        values = self.args.get("values")
6407        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6399    @property
6400    def keys(self) -> t.List[Expression]:
6401        keys = self.args.get("keys")
6402        return keys.expressions if keys else []
values: List[Expression]
6404    @property
6405    def values(self) -> t.List[Expression]:
6406        values = self.args.get("values")
6407        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6411class ToMap(Func):
6412    pass
key = 'tomap'
class MapFromEntries(Func):
6415class MapFromEntries(Func):
6416    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6420class ScopeResolution(Expression):
6421    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6424class Stream(Expression):
6425    pass
key = 'stream'
class StarMap(Func):
6428class StarMap(Func):
6429    pass
key = 'starmap'
class VarMap(Func):
6432class VarMap(Func):
6433    arg_types = {"keys": True, "values": True}
6434    is_var_len_args = True
6435
6436    @property
6437    def keys(self) -> t.List[Expression]:
6438        return self.args["keys"].expressions
6439
6440    @property
6441    def values(self) -> t.List[Expression]:
6442        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6436    @property
6437    def keys(self) -> t.List[Expression]:
6438        return self.args["keys"].expressions
values: List[Expression]
6440    @property
6441    def values(self) -> t.List[Expression]:
6442        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6446class MatchAgainst(Func):
6447    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6450class Max(AggFunc):
6451    arg_types = {"this": True, "expressions": False}
6452    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6455class MD5(Func):
6456    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6460class MD5Digest(Func):
6461    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6464class Median(AggFunc):
6465    pass
key = 'median'
class Min(AggFunc):
6468class Min(AggFunc):
6469    arg_types = {"this": True, "expressions": False}
6470    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6473class Month(Func):
6474    pass
key = 'month'
class AddMonths(Func):
6477class AddMonths(Func):
6478    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6481class Nvl2(Func):
6482    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6485class Normalize(Func):
6486    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6489class Overlay(Func):
6490    arg_types = {"this": True, "expression": True, "from": True, "for": False}
arg_types = {'this': True, 'expression': True, 'from': True, 'for': False}
key = 'overlay'
class Predict(Func):
6494class Predict(Func):
6495    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6498class Pow(Binary, Func):
6499    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6502class PercentileCont(AggFunc):
6503    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6506class PercentileDisc(AggFunc):
6507    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6510class Quantile(AggFunc):
6511    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6514class ApproxQuantile(Quantile):
6515    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
6518class Quarter(Func):
6519    pass
key = 'quarter'
class Rand(Func):
6524class Rand(Func):
6525    _sql_names = ["RAND", "RANDOM"]
6526    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6529class Randn(Func):
6530    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6533class RangeN(Func):
6534    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6537class ReadCSV(Func):
6538    _sql_names = ["READ_CSV"]
6539    is_var_len_args = True
6540    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6543class Reduce(Func):
6544    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):
6547class RegexpExtract(Func):
6548    arg_types = {
6549        "this": True,
6550        "expression": True,
6551        "position": False,
6552        "occurrence": False,
6553        "parameters": False,
6554        "group": False,
6555    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6558class RegexpExtractAll(Func):
6559    arg_types = {
6560        "this": True,
6561        "expression": True,
6562        "position": False,
6563        "occurrence": False,
6564        "parameters": False,
6565        "group": False,
6566    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6569class RegexpReplace(Func):
6570    arg_types = {
6571        "this": True,
6572        "expression": True,
6573        "replacement": False,
6574        "position": False,
6575        "occurrence": False,
6576        "modifiers": False,
6577    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6580class RegexpLike(Binary, Func):
6581    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6584class RegexpILike(Binary, Func):
6585    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6590class RegexpSplit(Func):
6591    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6594class Repeat(Func):
6595    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6600class Round(Func):
6601    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6604class RowNumber(Func):
6605    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6608class SafeDivide(Func):
6609    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6612class SHA(Func):
6613    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6616class SHA2(Func):
6617    _sql_names = ["SHA2"]
6618    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6621class Sign(Func):
6622    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6625class SortArray(Func):
6626    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6629class Split(Func):
6630    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6634class SplitPart(Func):
6635    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6640class Substring(Func):
6641    _sql_names = ["SUBSTRING", "SUBSTR"]
6642    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6645class StandardHash(Func):
6646    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6649class StartsWith(Func):
6650    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6651    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6654class StrPosition(Func):
6655    arg_types = {
6656        "this": True,
6657        "substr": True,
6658        "position": False,
6659        "occurrence": False,
6660    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6663class StrToDate(Func):
6664    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6667class StrToTime(Func):
6668    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
arg_types = {'this': True, 'format': True, 'zone': False, 'safe': False}
key = 'strtotime'
class StrToUnix(Func):
6673class StrToUnix(Func):
6674    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6679class StrToMap(Func):
6680    arg_types = {
6681        "this": True,
6682        "pair_delim": False,
6683        "key_value_delim": False,
6684        "duplicate_resolution_callback": False,
6685    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6688class NumberToStr(Func):
6689    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6692class FromBase(Func):
6693    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6696class Struct(Func):
6697    arg_types = {"expressions": False}
6698    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6701class StructExtract(Func):
6702    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6707class Stuff(Func):
6708    _sql_names = ["STUFF", "INSERT"]
6709    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):
6712class Sum(AggFunc):
6713    pass
key = 'sum'
class Sqrt(Func):
6716class Sqrt(Func):
6717    pass
key = 'sqrt'
class Stddev(AggFunc):
6720class Stddev(AggFunc):
6721    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6724class StddevPop(AggFunc):
6725    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6728class StddevSamp(AggFunc):
6729    pass
key = 'stddevsamp'
class Time(Func):
6733class Time(Func):
6734    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6737class TimeToStr(Func):
6738    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'zone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
6741class TimeToTimeStr(Func):
6742    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6745class TimeToUnix(Func):
6746    pass
key = 'timetounix'
class TimeStrToDate(Func):
6749class TimeStrToDate(Func):
6750    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6753class TimeStrToTime(Func):
6754    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6757class TimeStrToUnix(Func):
6758    pass
key = 'timestrtounix'
class Trim(Func):
6761class Trim(Func):
6762    arg_types = {
6763        "this": True,
6764        "expression": False,
6765        "position": False,
6766        "collation": False,
6767    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6770class TsOrDsAdd(Func, TimeUnit):
6771    # return_type is used to correctly cast the arguments of this expression when transpiling it
6772    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6773
6774    @property
6775    def return_type(self) -> DataType:
6776        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
6774    @property
6775    def return_type(self) -> DataType:
6776        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6779class TsOrDsDiff(Func, TimeUnit):
6780    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6783class TsOrDsToDateStr(Func):
6784    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6787class TsOrDsToDate(Func):
6788    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6791class TsOrDsToDatetime(Func):
6792    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6795class TsOrDsToTime(Func):
6796    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6799class TsOrDsToTimestamp(Func):
6800    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6803class TsOrDiToDi(Func):
6804    pass
key = 'tsorditodi'
class Unhex(Func):
6807class Unhex(Func):
6808    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6811class Unicode(Func):
6812    pass
key = 'unicode'
class UnixDate(Func):
6816class UnixDate(Func):
6817    pass
key = 'unixdate'
class UnixToStr(Func):
6820class UnixToStr(Func):
6821    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6826class UnixToTime(Func):
6827    arg_types = {
6828        "this": True,
6829        "scale": False,
6830        "zone": False,
6831        "hours": False,
6832        "minutes": False,
6833        "format": False,
6834    }
6835
6836    SECONDS = Literal.number(0)
6837    DECIS = Literal.number(1)
6838    CENTIS = Literal.number(2)
6839    MILLIS = Literal.number(3)
6840    DECIMILLIS = Literal.number(4)
6841    CENTIMILLIS = Literal.number(5)
6842    MICROS = Literal.number(6)
6843    DECIMICROS = Literal.number(7)
6844    CENTIMICROS = Literal.number(8)
6845    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False, 'format': False}
SECONDS = Literal(this=0, is_string=False)
DECIS = Literal(this=1, is_string=False)
CENTIS = Literal(this=2, is_string=False)
MILLIS = Literal(this=3, is_string=False)
DECIMILLIS = Literal(this=4, is_string=False)
CENTIMILLIS = Literal(this=5, is_string=False)
MICROS = Literal(this=6, is_string=False)
DECIMICROS = Literal(this=7, is_string=False)
CENTIMICROS = Literal(this=8, is_string=False)
NANOS = Literal(this=9, is_string=False)
key = 'unixtotime'
class UnixToTimeStr(Func):
6848class UnixToTimeStr(Func):
6849    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6852class UnixSeconds(Func):
6853    pass
key = 'unixseconds'
class Uuid(Func):
6856class Uuid(Func):
6857    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6858
6859    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6862class TimestampFromParts(Func):
6863    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6864    arg_types = {
6865        "year": True,
6866        "month": True,
6867        "day": True,
6868        "hour": True,
6869        "min": True,
6870        "sec": True,
6871        "nano": False,
6872        "zone": False,
6873        "milli": False,
6874    }
arg_types = {'year': True, 'month': True, 'day': True, 'hour': True, 'min': True, 'sec': True, 'nano': False, 'zone': False, 'milli': False}
key = 'timestampfromparts'
class Upper(Func):
6877class Upper(Func):
6878    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6881class Corr(Binary, AggFunc):
6882    pass
key = 'corr'
class Variance(AggFunc):
6885class Variance(AggFunc):
6886    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6889class VariancePop(AggFunc):
6890    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6893class CovarSamp(Binary, AggFunc):
6894    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6897class CovarPop(Binary, AggFunc):
6898    pass
key = 'covarpop'
class Week(Func):
6901class Week(Func):
6902    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6905class XMLElement(Func):
6906    _sql_names = ["XMLELEMENT"]
6907    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6910class XMLTable(Func):
6911    arg_types = {
6912        "this": True,
6913        "namespaces": False,
6914        "passing": False,
6915        "columns": False,
6916        "by_ref": False,
6917    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6920class XMLNamespace(Expression):
6921    pass
key = 'xmlnamespace'
class Year(Func):
6924class Year(Func):
6925    pass
key = 'year'
class Use(Expression):
6928class Use(Expression):
6929    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6932class Merge(DML):
6933    arg_types = {
6934        "this": True,
6935        "using": True,
6936        "on": True,
6937        "whens": True,
6938        "with": False,
6939        "returning": False,
6940    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6943class When(Expression):
6944    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class Whens(Expression):
6947class Whens(Expression):
6948    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6949
6950    arg_types = {"expressions": True}

Wraps around one or more WHEN [NOT] MATCHED [...] clauses.

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6955class NextValueFor(Func):
6956    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6961class Semicolon(Expression):
6962    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'SplitPart'>, <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 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_ASCII': <class 'IsAscii'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'CHAR_LENGTH': <class 'Length'>, 'CHARACTER_LENGTH': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OR': <class 'Or'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_SECONDS': <class 'UnixSeconds'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'UUID': <class 'Uuid'>, 'GEN_RANDOM_UUID': <class 'Uuid'>, 'GENERATE_UUID': <class 'Uuid'>, 'UUID_STRING': <class 'Uuid'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'XMLELEMENT': <class 'XMLElement'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
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, Type[sqlglot.dialects.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
7002def maybe_parse(
7003    sql_or_expression: ExpOrStr,
7004    *,
7005    into: t.Optional[IntoType] = None,
7006    dialect: DialectType = None,
7007    prefix: t.Optional[str] = None,
7008    copy: bool = False,
7009    **opts,
7010) -> Expression:
7011    """Gracefully handle a possible string or expression.
7012
7013    Example:
7014        >>> maybe_parse("1")
7015        Literal(this=1, is_string=False)
7016        >>> maybe_parse(to_identifier("x"))
7017        Identifier(this=x, quoted=False)
7018
7019    Args:
7020        sql_or_expression: the SQL code string or an expression
7021        into: the SQLGlot Expression to parse into
7022        dialect: the dialect used to parse the input expressions (in the case that an
7023            input expression is a SQL string).
7024        prefix: a string to prefix the sql with before it gets parsed
7025            (automatically includes a space)
7026        copy: whether to copy the expression.
7027        **opts: other options to use to parse the input expressions (again, in the case
7028            that an input expression is a SQL string).
7029
7030    Returns:
7031        Expression: the parsed or given expression.
7032    """
7033    if isinstance(sql_or_expression, Expression):
7034        if copy:
7035            return sql_or_expression.copy()
7036        return sql_or_expression
7037
7038    if sql_or_expression is None:
7039        raise ParseError("SQL cannot be None")
7040
7041    import sqlglot
7042
7043    sql = str(sql_or_expression)
7044    if prefix:
7045        sql = f"{prefix} {sql}"
7046
7047    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 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):
7058def maybe_copy(instance, copy=True):
7059    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7314def union(
7315    *expressions: ExpOrStr,
7316    distinct: bool = True,
7317    dialect: DialectType = None,
7318    copy: bool = True,
7319    **opts,
7320) -> Union:
7321    """
7322    Initializes a syntax tree for the `UNION` operation.
7323
7324    Example:
7325        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7326        'SELECT * FROM foo UNION SELECT * FROM bla'
7327
7328    Args:
7329        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7330            If `Expression` instances are passed, they will be used as-is.
7331        distinct: set the DISTINCT flag if and only if this is true.
7332        dialect: the dialect used to parse the input expression.
7333        copy: whether to copy the expression.
7334        opts: other options to use to parse the input expressions.
7335
7336    Returns:
7337        The new Union instance.
7338    """
7339    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7340    return _apply_set_operation(
7341        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7342    )

Initializes a syntax tree for the UNION operation.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the UNION's operands. If Expression instances are passed, they 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 to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7345def intersect(
7346    *expressions: ExpOrStr,
7347    distinct: bool = True,
7348    dialect: DialectType = None,
7349    copy: bool = True,
7350    **opts,
7351) -> Intersect:
7352    """
7353    Initializes a syntax tree for the `INTERSECT` operation.
7354
7355    Example:
7356        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7357        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7358
7359    Args:
7360        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7361            If `Expression` instances are passed, they will be used as-is.
7362        distinct: set the DISTINCT flag if and only if this is true.
7363        dialect: the dialect used to parse the input expression.
7364        copy: whether to copy the expression.
7365        opts: other options to use to parse the input expressions.
7366
7367    Returns:
7368        The new Intersect instance.
7369    """
7370    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7371    return _apply_set_operation(
7372        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7373    )

Initializes a syntax tree for the INTERSECT operation.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the INTERSECT's operands. If Expression instances are passed, they 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 to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7376def except_(
7377    *expressions: ExpOrStr,
7378    distinct: bool = True,
7379    dialect: DialectType = None,
7380    copy: bool = True,
7381    **opts,
7382) -> Except:
7383    """
7384    Initializes a syntax tree for the `EXCEPT` operation.
7385
7386    Example:
7387        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7388        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7389
7390    Args:
7391        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7392            If `Expression` instances are passed, they will be used as-is.
7393        distinct: set the DISTINCT flag if and only if this is true.
7394        dialect: the dialect used to parse the input expression.
7395        copy: whether to copy the expression.
7396        opts: other options to use to parse the input expressions.
7397
7398    Returns:
7399        The new Except instance.
7400    """
7401    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7402    return _apply_set_operation(
7403        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7404    )

Initializes a syntax tree for the EXCEPT operation.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the EXCEPT's operands. If Expression instances are passed, they 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 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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7407def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7408    """
7409    Initializes a syntax tree from one or multiple SELECT expressions.
7410
7411    Example:
7412        >>> select("col1", "col2").from_("tbl").sql()
7413        'SELECT col1, col2 FROM tbl'
7414
7415    Args:
7416        *expressions: the SQL code string to parse as the expressions of a
7417            SELECT statement. If an Expression instance is passed, this is used as-is.
7418        dialect: the dialect used to parse the input expressions (in the case that an
7419            input expression is a SQL string).
7420        **opts: other options to use to parse the input expressions (again, in the case
7421            that an input expression is a SQL string).
7422
7423    Returns:
7424        Select: the syntax tree for the SELECT statement.
7425    """
7426    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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7429def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7430    """
7431    Initializes a syntax tree from a FROM expression.
7432
7433    Example:
7434        >>> from_("tbl").select("col1", "col2").sql()
7435        'SELECT col1, col2 FROM tbl'
7436
7437    Args:
7438        *expression: the SQL code string to parse as the FROM expressions of a
7439            SELECT statement. If an Expression instance is passed, this is used as-is.
7440        dialect: the dialect used to parse the input expression (in the case that the
7441            input expression is a SQL string).
7442        **opts: other options to use to parse the input expressions (again, in the case
7443            that the input expression is a SQL string).
7444
7445    Returns:
7446        Select: the syntax tree for the SELECT statement.
7447    """
7448    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: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Update:
7451def update(
7452    table: str | Table,
7453    properties: t.Optional[dict] = None,
7454    where: t.Optional[ExpOrStr] = None,
7455    from_: t.Optional[ExpOrStr] = None,
7456    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7457    dialect: DialectType = None,
7458    **opts,
7459) -> Update:
7460    """
7461    Creates an update statement.
7462
7463    Example:
7464        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
7465        "WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
7466
7467    Args:
7468        properties: dictionary of properties to SET which are
7469            auto converted to sql objects eg None -> NULL
7470        where: sql conditional parsed into a WHERE statement
7471        from_: sql statement parsed into a FROM statement
7472        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7473        dialect: the dialect used to parse the input expressions.
7474        **opts: other options to use to parse the input expressions.
7475
7476    Returns:
7477        Update: the syntax tree for the UPDATE statement.
7478    """
7479    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7480    if properties:
7481        update_expr.set(
7482            "expressions",
7483            [
7484                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7485                for k, v in properties.items()
7486            ],
7487        )
7488    if from_:
7489        update_expr.set(
7490            "from",
7491            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7492        )
7493    if isinstance(where, Condition):
7494        where = Where(this=where)
7495    if where:
7496        update_expr.set(
7497            "where",
7498            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7499        )
7500    if with_:
7501        cte_list = [
7502            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7503            for alias, qry in with_.items()
7504        ]
7505        update_expr.set(
7506            "with",
7507            With(expressions=cte_list),
7508        )
7509    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
"WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
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
  • with_: dictionary of CTE aliases / select statements to include in a WITH clause.
  • 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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Delete:
7512def delete(
7513    table: ExpOrStr,
7514    where: t.Optional[ExpOrStr] = None,
7515    returning: t.Optional[ExpOrStr] = None,
7516    dialect: DialectType = None,
7517    **opts,
7518) -> Delete:
7519    """
7520    Builds a delete statement.
7521
7522    Example:
7523        >>> delete("my_table", where="id > 1").sql()
7524        'DELETE FROM my_table WHERE id > 1'
7525
7526    Args:
7527        where: sql conditional parsed into a WHERE statement
7528        returning: sql conditional parsed into a RETURNING statement
7529        dialect: the dialect used to parse the input expressions.
7530        **opts: other options to use to parse the input expressions.
7531
7532    Returns:
7533        Delete: the syntax tree for the DELETE statement.
7534    """
7535    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7536    if where:
7537        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7538    if returning:
7539        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7540    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[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7543def insert(
7544    expression: ExpOrStr,
7545    into: ExpOrStr,
7546    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7547    overwrite: t.Optional[bool] = None,
7548    returning: t.Optional[ExpOrStr] = None,
7549    dialect: DialectType = None,
7550    copy: bool = True,
7551    **opts,
7552) -> Insert:
7553    """
7554    Builds an INSERT statement.
7555
7556    Example:
7557        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7558        'INSERT INTO tbl VALUES (1, 2, 3)'
7559
7560    Args:
7561        expression: the sql string or expression of the INSERT statement
7562        into: the tbl to insert data to.
7563        columns: optionally the table's column names.
7564        overwrite: whether to INSERT OVERWRITE or not.
7565        returning: sql conditional parsed into a RETURNING statement
7566        dialect: the dialect used to parse the input expressions.
7567        copy: whether to copy the expression.
7568        **opts: other options to use to parse the input expressions.
7569
7570    Returns:
7571        Insert: the syntax tree for the INSERT statement.
7572    """
7573    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7574    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7575
7576    if columns:
7577        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7578
7579    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7580
7581    if returning:
7582        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7583
7584    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 to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7587def merge(
7588    *when_exprs: ExpOrStr,
7589    into: ExpOrStr,
7590    using: ExpOrStr,
7591    on: ExpOrStr,
7592    returning: t.Optional[ExpOrStr] = None,
7593    dialect: DialectType = None,
7594    copy: bool = True,
7595    **opts,
7596) -> Merge:
7597    """
7598    Builds a MERGE statement.
7599
7600    Example:
7601        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7602        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7603        ...       into="my_table",
7604        ...       using="source_table",
7605        ...       on="my_table.id = source_table.id").sql()
7606        'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
7607
7608    Args:
7609        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7610        into: The target table to merge data into.
7611        using: The source table to merge data from.
7612        on: The join condition for the merge.
7613        returning: The columns to return from the merge.
7614        dialect: The dialect used to parse the input expressions.
7615        copy: Whether to copy the expression.
7616        **opts: Other options to use to parse the input expressions.
7617
7618    Returns:
7619        Merge: The syntax tree for the MERGE statement.
7620    """
7621    expressions: t.List[Expression] = []
7622    for when_expr in when_exprs:
7623        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7624        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7625
7626    merge = Merge(
7627        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7628        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7629        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7630        whens=Whens(expressions=expressions),
7631    )
7632    if returning:
7633        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7634
7635    return merge

Builds a MERGE statement.

Example:
>>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
...       into="my_table",
...       using="source_table",
...       on="my_table.id = source_table.id").sql()
'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
Arguments:
  • *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
  • into: The target table to merge data into.
  • using: The source table to merge data from.
  • on: The join condition for the merge.
  • returning: The columns to return from the merge.
  • dialect: The dialect used to parse the input expressions.
  • copy: Whether to copy the expression.
  • **opts: Other options to use to parse the input expressions.
Returns:

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7638def condition(
7639    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7640) -> Condition:
7641    """
7642    Initialize a logical condition expression.
7643
7644    Example:
7645        >>> condition("x=1").sql()
7646        'x = 1'
7647
7648        This is helpful for composing larger logical syntax trees:
7649        >>> where = condition("x=1")
7650        >>> where = where.and_("y=1")
7651        >>> Select().from_("tbl").select("*").where(where).sql()
7652        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7653
7654    Args:
7655        *expression: the SQL code string to parse.
7656            If an Expression instance is passed, this is used as-is.
7657        dialect: the dialect used to parse the input expression (in the case that the
7658            input expression is a SQL string).
7659        copy: Whether to copy `expression` (only applies to expressions).
7660        **opts: other options to use to parse the input expressions (again, in the case
7661            that the input expression is a SQL string).
7662
7663    Returns:
7664        The new Condition instance
7665    """
7666    return maybe_parse(
7667        expression,
7668        into=Condition,
7669        dialect=dialect,
7670        copy=copy,
7671        **opts,
7672    )

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 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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7675def and_(
7676    *expressions: t.Optional[ExpOrStr],
7677    dialect: DialectType = None,
7678    copy: bool = True,
7679    wrap: bool = True,
7680    **opts,
7681) -> Condition:
7682    """
7683    Combine multiple conditions with an AND logical operator.
7684
7685    Example:
7686        >>> and_("x=1", and_("y=1", "z=1")).sql()
7687        'x = 1 AND (y = 1 AND z = 1)'
7688
7689    Args:
7690        *expressions: the SQL code strings to parse.
7691            If an Expression instance is passed, this is used as-is.
7692        dialect: the dialect used to parse the input expression.
7693        copy: whether to copy `expressions` (only applies to Expressions).
7694        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7695            precedence issues, but can be turned off when the produced AST is too deep and
7696            causes recursion-related issues.
7697        **opts: other options to use to parse the input expressions.
7698
7699    Returns:
7700        The new condition
7701    """
7702    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **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 to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7705def or_(
7706    *expressions: t.Optional[ExpOrStr],
7707    dialect: DialectType = None,
7708    copy: bool = True,
7709    wrap: bool = True,
7710    **opts,
7711) -> Condition:
7712    """
7713    Combine multiple conditions with an OR logical operator.
7714
7715    Example:
7716        >>> or_("x=1", or_("y=1", "z=1")).sql()
7717        'x = 1 OR (y = 1 OR z = 1)'
7718
7719    Args:
7720        *expressions: the SQL code strings to parse.
7721            If an Expression instance is passed, this is used as-is.
7722        dialect: the dialect used to parse the input expression.
7723        copy: whether to copy `expressions` (only applies to Expressions).
7724        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7725            precedence issues, but can be turned off when the produced AST is too deep and
7726            causes recursion-related issues.
7727        **opts: other options to use to parse the input expressions.
7728
7729    Returns:
7730        The new condition
7731    """
7732    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **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 to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7735def xor(
7736    *expressions: t.Optional[ExpOrStr],
7737    dialect: DialectType = None,
7738    copy: bool = True,
7739    wrap: bool = True,
7740    **opts,
7741) -> Condition:
7742    """
7743    Combine multiple conditions with an XOR logical operator.
7744
7745    Example:
7746        >>> xor("x=1", xor("y=1", "z=1")).sql()
7747        'x = 1 XOR (y = 1 XOR z = 1)'
7748
7749    Args:
7750        *expressions: the SQL code strings to parse.
7751            If an Expression instance is passed, this is used as-is.
7752        dialect: the dialect used to parse the input expression.
7753        copy: whether to copy `expressions` (only applies to Expressions).
7754        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7755            precedence issues, but can be turned off when the produced AST is too deep and
7756            causes recursion-related issues.
7757        **opts: other options to use to parse the input expressions.
7758
7759    Returns:
7760        The new condition
7761    """
7762    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an XOR logical operator.

Example:
>>> xor("x=1", xor("y=1", "z=1")).sql()
'x = 1 XOR (y = 1 XOR 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 to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7765def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7766    """
7767    Wrap a condition with a NOT operator.
7768
7769    Example:
7770        >>> not_("this_suit='black'").sql()
7771        "NOT this_suit = 'black'"
7772
7773    Args:
7774        expression: the SQL code string to parse.
7775            If an Expression instance is passed, this is used as-is.
7776        dialect: the dialect used to parse the input expression.
7777        copy: whether to copy the expression or not.
7778        **opts: other options to use to parse the input expressions.
7779
7780    Returns:
7781        The new condition.
7782    """
7783    this = condition(
7784        expression,
7785        dialect=dialect,
7786        copy=copy,
7787        **opts,
7788    )
7789    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:
7792def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7793    """
7794    Wrap an expression in parentheses.
7795
7796    Example:
7797        >>> paren("5 + 3").sql()
7798        '(5 + 3)'
7799
7800    Args:
7801        expression: the SQL code string to parse.
7802            If an Expression instance is passed, this is used as-is.
7803        copy: whether to copy the expression or not.
7804
7805    Returns:
7806        The wrapped expression.
7807    """
7808    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: Pattern[str] = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
7824def to_identifier(name, quoted=None, copy=True):
7825    """Builds an identifier.
7826
7827    Args:
7828        name: The name to turn into an identifier.
7829        quoted: Whether to force quote the identifier.
7830        copy: Whether to copy name if it's an Identifier.
7831
7832    Returns:
7833        The identifier ast node.
7834    """
7835
7836    if name is None:
7837        return None
7838
7839    if isinstance(name, Identifier):
7840        identifier = maybe_copy(name, copy)
7841    elif isinstance(name, str):
7842        identifier = Identifier(
7843            this=name,
7844            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7845        )
7846    else:
7847        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7848    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether 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, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Identifier:
7851def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7852    """
7853    Parses a given string into an identifier.
7854
7855    Args:
7856        name: The name to parse into an identifier.
7857        dialect: The dialect to parse against.
7858
7859    Returns:
7860        The identifier ast node.
7861    """
7862    try:
7863        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7864    except (ParseError, TokenError):
7865        expression = to_identifier(name)
7866
7867    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:
7873def to_interval(interval: str | Literal) -> Interval:
7874    """Builds an interval expression from a string like '1 day' or '5 months'."""
7875    if isinstance(interval, Literal):
7876        if not interval.is_string:
7877            raise ValueError("Invalid interval string.")
7878
7879        interval = interval.this
7880
7881    interval = maybe_parse(f"INTERVAL {interval}")
7882    assert isinstance(interval, Interval)
7883    return interval

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
7886def to_table(
7887    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7888) -> Table:
7889    """
7890    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7891    If a table is passed in then that table is returned.
7892
7893    Args:
7894        sql_path: a `[catalog].[schema].[table]` string.
7895        dialect: the source dialect according to which the table name will be parsed.
7896        copy: Whether to copy a table if it is passed in.
7897        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7898
7899    Returns:
7900        A table expression.
7901    """
7902    if isinstance(sql_path, Table):
7903        return maybe_copy(sql_path, copy=copy)
7904
7905    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7906
7907    for k, v in kwargs.items():
7908        table.set(k, v)
7909
7910    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
7913def to_column(
7914    sql_path: str | Column,
7915    quoted: t.Optional[bool] = None,
7916    dialect: DialectType = None,
7917    copy: bool = True,
7918    **kwargs,
7919) -> Column:
7920    """
7921    Create a column from a `[table].[column]` sql path. Table is optional.
7922    If a column is passed in then that column is returned.
7923
7924    Args:
7925        sql_path: a `[table].[column]` string.
7926        quoted: Whether or not to force quote identifiers.
7927        dialect: the source dialect according to which the column name will be parsed.
7928        copy: Whether to copy a column if it is passed in.
7929        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7930
7931    Returns:
7932        A column expression.
7933    """
7934    if isinstance(sql_path, Column):
7935        return maybe_copy(sql_path, copy=copy)
7936
7937    try:
7938        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7939    except ParseError:
7940        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7941
7942    for k, v in kwargs.items():
7943        col.set(k, v)
7944
7945    if quoted:
7946        for i in col.find_all(Identifier):
7947            i.set("quoted", True)
7948
7949    return col

Create a column from a [table].[column] sql path. Table is optional. If a column is passed in then that column is returned.

Arguments:
  • sql_path: a [table].[column] string.
  • quoted: Whether or not to force quote identifiers.
  • dialect: the source dialect according to which the column name will be parsed.
  • copy: Whether to copy a column if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Column expression with.
Returns:

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts):
7952def alias_(
7953    expression: ExpOrStr,
7954    alias: t.Optional[str | Identifier],
7955    table: bool | t.Sequence[str | Identifier] = False,
7956    quoted: t.Optional[bool] = None,
7957    dialect: DialectType = None,
7958    copy: bool = True,
7959    **opts,
7960):
7961    """Create an Alias expression.
7962
7963    Example:
7964        >>> alias_('foo', 'bar').sql()
7965        'foo AS bar'
7966
7967        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7968        '(SELECT 1, 2) AS bar(a, b)'
7969
7970    Args:
7971        expression: the SQL code strings to parse.
7972            If an Expression instance is passed, this is used as-is.
7973        alias: the alias name to use. If the name has
7974            special characters it is quoted.
7975        table: Whether to create a table alias, can also be a list of columns.
7976        quoted: whether to quote the alias
7977        dialect: the dialect used to parse the input expression.
7978        copy: Whether to copy the expression.
7979        **opts: other options to use to parse the input expressions.
7980
7981    Returns:
7982        Alias: the aliased expression
7983    """
7984    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7985    alias = to_identifier(alias, quoted=quoted)
7986
7987    if table:
7988        table_alias = TableAlias(this=alias)
7989        exp.set("alias", table_alias)
7990
7991        if not isinstance(table, bool):
7992            for column in table:
7993                table_alias.append("columns", to_identifier(column, quoted=quoted))
7994
7995        return exp
7996
7997    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7998    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7999    # for the complete Window expression.
8000    #
8001    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8002
8003    if "alias" in exp.arg_types and not isinstance(exp, Window):
8004        exp.set("alias", alias)
8005        return exp
8006    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 to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether 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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8009def subquery(
8010    expression: ExpOrStr,
8011    alias: t.Optional[Identifier | str] = None,
8012    dialect: DialectType = None,
8013    **opts,
8014) -> Select:
8015    """
8016    Build a subquery expression that's selected from.
8017
8018    Example:
8019        >>> subquery('select x from tbl', 'bar').select('x').sql()
8020        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8021
8022    Args:
8023        expression: the SQL code strings to parse.
8024            If an Expression instance is passed, this is used as-is.
8025        alias: the alias name to use.
8026        dialect: the dialect used to parse the input expression.
8027        **opts: other options to use to parse the input expressions.
8028
8029    Returns:
8030        A new Select instance with the subquery expression included.
8031    """
8032
8033    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8034    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression that's selected from.

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, table=None, db=None, catalog=None, *, fields=None, quoted=None, copy=True):
8065def column(
8066    col,
8067    table=None,
8068    db=None,
8069    catalog=None,
8070    *,
8071    fields=None,
8072    quoted=None,
8073    copy=True,
8074):
8075    """
8076    Build a Column.
8077
8078    Args:
8079        col: Column name.
8080        table: Table name.
8081        db: Database name.
8082        catalog: Catalog name.
8083        fields: Additional fields using dots.
8084        quoted: Whether to force quotes on the column's identifiers.
8085        copy: Whether to copy identifiers if passed in.
8086
8087    Returns:
8088        The new Column instance.
8089    """
8090    this = Column(
8091        this=to_identifier(col, quoted=quoted, copy=copy),
8092        table=to_identifier(table, quoted=quoted, copy=copy),
8093        db=to_identifier(db, quoted=quoted, copy=copy),
8094        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8095    )
8096
8097    if fields:
8098        this = Dot.build(
8099            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8100        )
8101    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8104def cast(
8105    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8106) -> Cast:
8107    """Cast an expression to a data type.
8108
8109    Example:
8110        >>> cast('x + 1', 'int').sql()
8111        'CAST(x + 1 AS INT)'
8112
8113    Args:
8114        expression: The expression to cast.
8115        to: The datatype to cast to.
8116        copy: Whether to copy the supplied expressions.
8117        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8118            - The expression to be cast is already a exp.Cast expression
8119            - The existing cast is to a type that is logically equivalent to new type
8120
8121            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8122            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8123            and instead just return the original expression `CAST(x as DATETIME)`.
8124
8125            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8126            mapping is applied in the target dialect generator.
8127
8128    Returns:
8129        The new Cast instance.
8130    """
8131    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8132    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8133
8134    # dont re-cast if the expression is already a cast to the correct type
8135    if isinstance(expr, Cast):
8136        from sqlglot.dialects.dialect import Dialect
8137
8138        target_dialect = Dialect.get_or_raise(dialect)
8139        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8140
8141        existing_cast_type: DataType.Type = expr.to.this
8142        new_cast_type: DataType.Type = data_type.this
8143        types_are_equivalent = type_mapping.get(
8144            existing_cast_type, existing_cast_type.value
8145        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8146
8147        if expr.is_type(data_type) or types_are_equivalent:
8148            return expr
8149
8150    expr = Cast(this=expr, to=data_type)
8151    expr.type = data_type
8152
8153    return expr

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.
  • copy: Whether to copy the supplied expressions.
  • dialect: The target dialect. This is used to prevent a re-cast in the following scenario:

    • The expression to be cast is already a exp.Cast expression
    • The existing cast is to a type that is logically equivalent to new type

    For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP, but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return CAST(x (as DATETIME) as TIMESTAMP) and instead just return the original expression CAST(x as DATETIME).

    This is to prevent it being output as a double cast CAST(x (as TIMESTAMP) as TIMESTAMP) once the DATETIME -> TIMESTAMP mapping is applied in the target dialect generator.

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:
8156def table_(
8157    table: Identifier | str,
8158    db: t.Optional[Identifier | str] = None,
8159    catalog: t.Optional[Identifier | str] = None,
8160    quoted: t.Optional[bool] = None,
8161    alias: t.Optional[Identifier | str] = None,
8162) -> Table:
8163    """Build a Table.
8164
8165    Args:
8166        table: Table name.
8167        db: Database name.
8168        catalog: Catalog name.
8169        quote: Whether to force quotes on the table's identifiers.
8170        alias: Table's alias.
8171
8172    Returns:
8173        The new Table instance.
8174    """
8175    return Table(
8176        this=to_identifier(table, quoted=quoted) if table else None,
8177        db=to_identifier(db, quoted=quoted) if db else None,
8178        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8179        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8180    )

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:
8183def values(
8184    values: t.Iterable[t.Tuple[t.Any, ...]],
8185    alias: t.Optional[str] = None,
8186    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8187) -> Values:
8188    """Build VALUES statement.
8189
8190    Example:
8191        >>> values([(1, '2')]).sql()
8192        "VALUES (1, '2')"
8193
8194    Args:
8195        values: values statements that will be converted to SQL
8196        alias: optional alias
8197        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8198         If either are provided then an alias is also required.
8199
8200    Returns:
8201        Values: the Values expression object
8202    """
8203    if columns and not alias:
8204        raise ValueError("Alias is required when providing columns")
8205
8206    return Values(
8207        expressions=[convert(tup) for tup in values],
8208        alias=(
8209            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8210            if columns
8211            else (TableAlias(this=to_identifier(alias)) if alias else None)
8212        ),
8213    )

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:
8216def var(name: t.Optional[ExpOrStr]) -> Var:
8217    """Build a SQL variable.
8218
8219    Example:
8220        >>> repr(var('x'))
8221        'Var(this=x)'
8222
8223        >>> repr(var(column('x', table='y')))
8224        'Var(this=x)'
8225
8226    Args:
8227        name: The name of the var or an expression who's name will become the var.
8228
8229    Returns:
8230        The new variable node.
8231    """
8232    if not name:
8233        raise ValueError("Cannot convert empty name into var.")
8234
8235    if isinstance(name, Expression):
8236        name = name.name
8237    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, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8240def rename_table(
8241    old_name: str | Table,
8242    new_name: str | Table,
8243    dialect: DialectType = None,
8244) -> Alter:
8245    """Build ALTER TABLE... RENAME... expression
8246
8247    Args:
8248        old_name: The old name of the table
8249        new_name: The new name of the table
8250        dialect: The dialect to parse the table.
8251
8252    Returns:
8253        Alter table expression
8254    """
8255    old_table = to_table(old_name, dialect=dialect)
8256    new_table = to_table(new_name, dialect=dialect)
8257    return Alter(
8258        this=old_table,
8259        kind="TABLE",
8260        actions=[
8261            AlterRename(this=new_table),
8262        ],
8263    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse the table.
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8266def rename_column(
8267    table_name: str | Table,
8268    old_column_name: str | Column,
8269    new_column_name: str | Column,
8270    exists: t.Optional[bool] = None,
8271    dialect: DialectType = None,
8272) -> Alter:
8273    """Build ALTER TABLE... RENAME COLUMN... expression
8274
8275    Args:
8276        table_name: Name of the table
8277        old_column: The old name of the column
8278        new_column: The new name of the column
8279        exists: Whether to add the `IF EXISTS` clause
8280        dialect: The dialect to parse the table/column.
8281
8282    Returns:
8283        Alter table expression
8284    """
8285    table = to_table(table_name, dialect=dialect)
8286    old_column = to_column(old_column_name, dialect=dialect)
8287    new_column = to_column(new_column_name, dialect=dialect)
8288    return Alter(
8289        this=table,
8290        kind="TABLE",
8291        actions=[
8292            RenameColumn(this=old_column, to=new_column, exists=exists),
8293        ],
8294    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether to add the IF EXISTS clause
  • dialect: The dialect to parse the table/column.
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
8297def convert(value: t.Any, copy: bool = False) -> Expression:
8298    """Convert a python value into an expression object.
8299
8300    Raises an error if a conversion is not possible.
8301
8302    Args:
8303        value: A python object.
8304        copy: Whether to copy `value` (only applies to Expressions and collections).
8305
8306    Returns:
8307        The equivalent expression object.
8308    """
8309    if isinstance(value, Expression):
8310        return maybe_copy(value, copy)
8311    if isinstance(value, str):
8312        return Literal.string(value)
8313    if isinstance(value, bool):
8314        return Boolean(this=value)
8315    if value is None or (isinstance(value, float) and math.isnan(value)):
8316        return null()
8317    if isinstance(value, numbers.Number):
8318        return Literal.number(value)
8319    if isinstance(value, bytes):
8320        return HexString(this=value.hex())
8321    if isinstance(value, datetime.datetime):
8322        datetime_literal = Literal.string(value.isoformat(sep=" "))
8323
8324        tz = None
8325        if value.tzinfo:
8326            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8327            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8328            tz = Literal.string(str(value.tzinfo))
8329
8330        return TimeStrToTime(this=datetime_literal, zone=tz)
8331    if isinstance(value, datetime.date):
8332        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8333        return DateStrToDate(this=date_literal)
8334    if isinstance(value, tuple):
8335        if hasattr(value, "_fields"):
8336            return Struct(
8337                expressions=[
8338                    PropertyEQ(
8339                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8340                    )
8341                    for k in value._fields
8342                ]
8343            )
8344        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8345    if isinstance(value, list):
8346        return Array(expressions=[convert(v, copy=copy) for v in value])
8347    if isinstance(value, dict):
8348        return Map(
8349            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8350            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8351        )
8352    if hasattr(value, "__dict__"):
8353        return Struct(
8354            expressions=[
8355                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8356                for k, v in value.__dict__.items()
8357            ]
8358        )
8359    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 to copy value (only applies to Expressions and collections).
Returns:

The equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
8362def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8363    """
8364    Replace children of an expression with the result of a lambda fun(child) -> exp.
8365    """
8366    for k, v in tuple(expression.args.items()):
8367        is_list_arg = type(v) is list
8368
8369        child_nodes = v if is_list_arg else [v]
8370        new_child_nodes = []
8371
8372        for cn in child_nodes:
8373            if isinstance(cn, Expression):
8374                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8375                    new_child_nodes.append(child_node)
8376            else:
8377                new_child_nodes.append(cn)
8378
8379        expression.set(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 replace_tree( expression: Expression, fun: Callable, prune: Optional[Callable[[Expression], bool]] = None) -> Expression:
8382def replace_tree(
8383    expression: Expression,
8384    fun: t.Callable,
8385    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8386) -> Expression:
8387    """
8388    Replace an entire tree with the result of function calls on each node.
8389
8390    This will be traversed in reverse dfs, so leaves first.
8391    If new nodes are created as a result of function calls, they will also be traversed.
8392    """
8393    stack = list(expression.dfs(prune=prune))
8394
8395    while stack:
8396        node = stack.pop()
8397        new_node = fun(node)
8398
8399        if new_node is not node:
8400            node.replace(new_node)
8401
8402            if isinstance(new_node, Expression):
8403                stack.append(new_node)
8404
8405    return new_node

Replace an entire tree with the result of function calls on each node.

This will be traversed in reverse dfs, so leaves first. If new nodes are created as a result of function calls, they will also be traversed.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
8408def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8409    """
8410    Return all table names referenced through columns in an expression.
8411
8412    Example:
8413        >>> import sqlglot
8414        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8415        ['a', 'c']
8416
8417    Args:
8418        expression: expression to find table names.
8419        exclude: a table name to exclude
8420
8421    Returns:
8422        A list of unique names.
8423    """
8424    return {
8425        table
8426        for table in (column.table for column in expression.find_all(Column))
8427        if table and table != exclude
8428    }

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, Type[sqlglot.dialects.Dialect], NoneType] = None, identify: bool = False) -> str:
8431def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8432    """Get the full name of a table as a string.
8433
8434    Args:
8435        table: Table expression node or string.
8436        dialect: The dialect to generate the table name for.
8437        identify: Determines when an identifier should be quoted. Possible values are:
8438            False (default): Never quote, except in cases where it's mandatory by the dialect.
8439            True: Always quote.
8440
8441    Examples:
8442        >>> from sqlglot import exp, parse_one
8443        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8444        'a.b.c'
8445
8446    Returns:
8447        The table name.
8448    """
8449
8450    table = maybe_parse(table, into=Table, dialect=dialect)
8451
8452    if not table:
8453        raise ValueError(f"Cannot parse {table}")
8454
8455    return ".".join(
8456        (
8457            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8458            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8459            else part.name
8460        )
8461        for part in table.parts
8462    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> str:
8465def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8466    """Returns a case normalized table name without quotes.
8467
8468    Args:
8469        table: the table to normalize
8470        dialect: the dialect to use for normalization rules
8471        copy: whether to copy the expression.
8472
8473    Examples:
8474        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8475        'A-B.c'
8476    """
8477    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8478
8479    return ".".join(
8480        p.name
8481        for p in normalize_identifiers(
8482            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8483        ).parts
8484    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8487def replace_tables(
8488    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8489) -> E:
8490    """Replace all tables in expression according to the mapping.
8491
8492    Args:
8493        expression: expression node to be transformed and replaced.
8494        mapping: mapping of table names.
8495        dialect: the dialect of the mapping table
8496        copy: whether to copy the expression.
8497
8498    Examples:
8499        >>> from sqlglot import exp, parse_one
8500        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8501        'SELECT * FROM c /* a.b */'
8502
8503    Returns:
8504        The mapped expression.
8505    """
8506
8507    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8508
8509    def _replace_tables(node: Expression) -> Expression:
8510        if isinstance(node, Table) and node.meta.get("replace") is not False:
8511            original = normalize_table_name(node, dialect=dialect)
8512            new_name = mapping.get(original)
8513
8514            if new_name:
8515                table = to_table(
8516                    new_name,
8517                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8518                    dialect=dialect,
8519                )
8520                table.add_comments([original])
8521                return table
8522        return node
8523
8524    return expression.transform(_replace_tables, copy=copy)  # type: ignore

Replace all tables in expression according to the mapping.

Arguments:
  • expression: expression node to be transformed and replaced.
  • mapping: mapping of table names.
  • dialect: the dialect of the mapping table
  • copy: whether 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 /* a.b */'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
8527def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8528    """Replace placeholders in an expression.
8529
8530    Args:
8531        expression: expression node to be transformed and replaced.
8532        args: positional names that will substitute unnamed placeholders in the given order.
8533        kwargs: keyword arguments that will substitute named placeholders.
8534
8535    Examples:
8536        >>> from sqlglot import exp, parse_one
8537        >>> replace_placeholders(
8538        ...     parse_one("select * from :tbl where ? = ?"),
8539        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8540        ... ).sql()
8541        "SELECT * FROM foo WHERE str_col = 'b'"
8542
8543    Returns:
8544        The mapped expression.
8545    """
8546
8547    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8548        if isinstance(node, Placeholder):
8549            if node.this:
8550                new_name = kwargs.get(node.this)
8551                if new_name is not None:
8552                    return convert(new_name)
8553            else:
8554                try:
8555                    return convert(next(args))
8556                except StopIteration:
8557                    pass
8558        return node
8559
8560    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, Union[Query, Callable[[], Query]]], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8563def expand(
8564    expression: Expression,
8565    sources: t.Dict[str, Query | t.Callable[[], Query]],
8566    dialect: DialectType = None,
8567    copy: bool = True,
8568) -> Expression:
8569    """Transforms an expression by expanding all referenced sources into subqueries.
8570
8571    Examples:
8572        >>> from sqlglot import parse_one
8573        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8574        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8575
8576        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8577        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8578
8579    Args:
8580        expression: The expression to expand.
8581        sources: A dict of name to query or a callable that provides a query on demand.
8582        dialect: The dialect of the sources dict or the callable.
8583        copy: Whether to copy the expression during transformation. Defaults to True.
8584
8585    Returns:
8586        The transformed expression.
8587    """
8588    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8589
8590    def _expand(node: Expression):
8591        if isinstance(node, Table):
8592            name = normalize_table_name(node, dialect=dialect)
8593            source = normalized_sources.get(name)
8594
8595            if source:
8596                # Create a subquery with the same alias (or table name if no alias)
8597                parsed_source = source() if callable(source) else source
8598                subquery = parsed_source.subquery(node.alias or name)
8599                subquery.comments = [f"source: {name}"]
8600
8601                # Continue expanding within the subquery
8602                return subquery.transform(_expand, copy=False)
8603
8604        return node
8605
8606    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 dict of name to query or a callable that provides a query on demand.
  • dialect: The dialect of the sources dict or the callable.
  • copy: Whether to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Func:
8609def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8610    """
8611    Returns a Func expression.
8612
8613    Examples:
8614        >>> func("abs", 5).sql()
8615        'ABS(5)'
8616
8617        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8618        'CAST(5 AS DOUBLE)'
8619
8620    Args:
8621        name: the name of the function to build.
8622        args: the args used to instantiate the function of interest.
8623        copy: whether to copy the argument expressions.
8624        dialect: the source dialect.
8625        kwargs: the kwargs used to instantiate the function of interest.
8626
8627    Note:
8628        The arguments `args` and `kwargs` are mutually exclusive.
8629
8630    Returns:
8631        An instance of the function of interest, or an anonymous function, if `name` doesn't
8632        correspond to an existing `sqlglot.expressions.Func` class.
8633    """
8634    if args and kwargs:
8635        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8636
8637    from sqlglot.dialects.dialect import Dialect
8638
8639    dialect = Dialect.get_or_raise(dialect)
8640
8641    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8642    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8643
8644    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8645    if constructor:
8646        if converted:
8647            if "dialect" in constructor.__code__.co_varnames:
8648                function = constructor(converted, dialect=dialect)
8649            else:
8650                function = constructor(converted)
8651        elif constructor.__name__ == "from_arg_list":
8652            function = constructor.__self__(**kwargs)  # type: ignore
8653        else:
8654            constructor = FUNCTION_BY_NAME.get(name.upper())
8655            if constructor:
8656                function = constructor(**kwargs)
8657            else:
8658                raise ValueError(
8659                    f"Unable to convert '{name}' into a Func. Either manually construct "
8660                    "the Func expression of interest or parse the function call."
8661                )
8662    else:
8663        kwargs = kwargs or {"expressions": converted}
8664        function = Anonymous(this=name, **kwargs)
8665
8666    for error_message in function.error_messages(converted):
8667        raise ValueError(error_message)
8668
8669    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.
  • copy: whether to copy the argument expressions.
  • 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 sqlglot.expressions.Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
8672def case(
8673    expression: t.Optional[ExpOrStr] = None,
8674    **opts,
8675) -> Case:
8676    """
8677    Initialize a CASE statement.
8678
8679    Example:
8680        case().when("a = 1", "foo").else_("bar")
8681
8682    Args:
8683        expression: Optionally, the input expression (not all dialects support this)
8684        **opts: Extra keyword arguments for parsing `expression`
8685    """
8686    if expression is not None:
8687        this = maybe_parse(expression, **opts)
8688    else:
8689        this = None
8690    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 array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Array:
8693def array(
8694    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8695) -> Array:
8696    """
8697    Returns an array.
8698
8699    Examples:
8700        >>> array(1, 'x').sql()
8701        'ARRAY(1, x)'
8702
8703    Args:
8704        expressions: the expressions to add to the array.
8705        copy: whether to copy the argument expressions.
8706        dialect: the source dialect.
8707        kwargs: the kwargs used to instantiate the function of interest.
8708
8709    Returns:
8710        An array expression.
8711    """
8712    return Array(
8713        expressions=[
8714            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8715            for expression in expressions
8716        ]
8717    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Tuple:
8720def tuple_(
8721    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8722) -> Tuple:
8723    """
8724    Returns an tuple.
8725
8726    Examples:
8727        >>> tuple_(1, 'x').sql()
8728        '(1, x)'
8729
8730    Args:
8731        expressions: the expressions to add to the tuple.
8732        copy: whether to copy the argument expressions.
8733        dialect: the source dialect.
8734        kwargs: the kwargs used to instantiate the function of interest.
8735
8736    Returns:
8737        A tuple expression.
8738    """
8739    return Tuple(
8740        expressions=[
8741            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8742            for expression in expressions
8743        ]
8744    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

A tuple expression.

def true() -> Boolean:
8747def true() -> Boolean:
8748    """
8749    Returns a true Boolean expression.
8750    """
8751    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8754def false() -> Boolean:
8755    """
8756    Returns a false Boolean expression.
8757    """
8758    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8761def null() -> Null:
8762    """
8763    Returns a Null expression.
8764    """
8765    return Null()

Returns a Null expression.

NONNULL_CONSTANTS = (<class 'Literal'>, <class 'Boolean'>)
CONSTANTS = (<class 'Literal'>, <class 'Boolean'>, <class 'Null'>)