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

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

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):
2061class Drop(Expression):
2062    arg_types = {
2063        "this": False,
2064        "kind": False,
2065        "expressions": False,
2066        "exists": False,
2067        "temporary": False,
2068        "materialized": False,
2069        "cascade": False,
2070        "constraints": False,
2071        "purge": False,
2072        "cluster": False,
2073        "concurrently": False,
2074    }
2075
2076    @property
2077    def kind(self) -> t.Optional[str]:
2078        kind = self.args.get("kind")
2079        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]
2076    @property
2077    def kind(self) -> t.Optional[str]:
2078        kind = self.args.get("kind")
2079        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2083class Export(Expression):
2084    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2087class Filter(Expression):
2088    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2091class Check(Expression):
2092    pass
key = 'check'
class Changes(Expression):
2095class Changes(Expression):
2096    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2100class Connect(Expression):
2101    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2104class CopyParameter(Expression):
2105    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2108class Copy(DML):
2109    arg_types = {
2110        "this": True,
2111        "kind": True,
2112        "files": True,
2113        "credentials": False,
2114        "format": False,
2115        "params": False,
2116    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2119class Credentials(Expression):
2120    arg_types = {
2121        "credentials": False,
2122        "encryption": False,
2123        "storage": False,
2124        "iam_role": False,
2125        "region": False,
2126    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2129class Prior(Expression):
2130    pass
key = 'prior'
class Directory(Expression):
2133class Directory(Expression):
2134    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2135    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2138class ForeignKey(Expression):
2139    arg_types = {
2140        "expressions": False,
2141        "reference": False,
2142        "delete": False,
2143        "update": False,
2144    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2147class ColumnPrefix(Expression):
2148    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2151class PrimaryKey(Expression):
2152    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2157class Into(Expression):
2158    arg_types = {
2159        "this": False,
2160        "temporary": False,
2161        "unlogged": False,
2162        "bulk_collect": False,
2163        "expressions": False,
2164    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2167class From(Expression):
2168    @property
2169    def name(self) -> str:
2170        return self.this.name
2171
2172    @property
2173    def alias_or_name(self) -> str:
2174        return self.this.alias_or_name
name: str
2168    @property
2169    def name(self) -> str:
2170        return self.this.name
alias_or_name: str
2172    @property
2173    def alias_or_name(self) -> str:
2174        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2177class Having(Expression):
2178    pass
key = 'having'
class Hint(Expression):
2181class Hint(Expression):
2182    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2185class JoinHint(Expression):
2186    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2189class Identifier(Expression):
2190    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2191
2192    @property
2193    def quoted(self) -> bool:
2194        return bool(self.args.get("quoted"))
2195
2196    @property
2197    def hashable_args(self) -> t.Any:
2198        return (self.this, self.quoted)
2199
2200    @property
2201    def output_name(self) -> str:
2202        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2192    @property
2193    def quoted(self) -> bool:
2194        return bool(self.args.get("quoted"))
hashable_args: Any
2196    @property
2197    def hashable_args(self) -> t.Any:
2198        return (self.this, self.quoted)
output_name: str
2200    @property
2201    def output_name(self) -> str:
2202        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):
2206class Opclass(Expression):
2207    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2210class Index(Expression):
2211    arg_types = {
2212        "this": False,
2213        "table": False,
2214        "unique": False,
2215        "primary": False,
2216        "amp": False,  # teradata
2217        "params": False,
2218    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2221class IndexParameters(Expression):
2222    arg_types = {
2223        "using": False,
2224        "include": False,
2225        "columns": False,
2226        "with_storage": False,
2227        "partition_by": False,
2228        "tablespace": False,
2229        "where": False,
2230        "on": False,
2231    }
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):
2234class Insert(DDL, DML):
2235    arg_types = {
2236        "hint": False,
2237        "with": False,
2238        "is_function": False,
2239        "this": False,
2240        "expression": False,
2241        "conflict": False,
2242        "returning": False,
2243        "overwrite": False,
2244        "exists": False,
2245        "alternative": False,
2246        "where": False,
2247        "ignore": False,
2248        "by_name": False,
2249        "stored": False,
2250        "partition": False,
2251        "settings": False,
2252        "source": False,
2253    }
2254
2255    def with_(
2256        self,
2257        alias: ExpOrStr,
2258        as_: ExpOrStr,
2259        recursive: t.Optional[bool] = None,
2260        materialized: t.Optional[bool] = None,
2261        append: bool = True,
2262        dialect: DialectType = None,
2263        copy: bool = True,
2264        **opts,
2265    ) -> Insert:
2266        """
2267        Append to or set the common table expressions.
2268
2269        Example:
2270            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2271            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2272
2273        Args:
2274            alias: the SQL code string to parse as the table name.
2275                If an `Expression` instance is passed, this is used as-is.
2276            as_: the SQL code string to parse as the table expression.
2277                If an `Expression` instance is passed, it will be used as-is.
2278            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2279            materialized: set the MATERIALIZED part of the expression.
2280            append: if `True`, add to any existing expressions.
2281                Otherwise, this resets the expressions.
2282            dialect: the dialect used to parse the input expression.
2283            copy: if `False`, modify this expression instance in-place.
2284            opts: other options to use to parse the input expressions.
2285
2286        Returns:
2287            The modified expression.
2288        """
2289        return _apply_cte_builder(
2290            self,
2291            alias,
2292            as_,
2293            recursive=recursive,
2294            materialized=materialized,
2295            append=append,
2296            dialect=dialect,
2297            copy=copy,
2298            **opts,
2299        )
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:
2255    def with_(
2256        self,
2257        alias: ExpOrStr,
2258        as_: ExpOrStr,
2259        recursive: t.Optional[bool] = None,
2260        materialized: t.Optional[bool] = None,
2261        append: bool = True,
2262        dialect: DialectType = None,
2263        copy: bool = True,
2264        **opts,
2265    ) -> Insert:
2266        """
2267        Append to or set the common table expressions.
2268
2269        Example:
2270            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2271            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2272
2273        Args:
2274            alias: the SQL code string to parse as the table name.
2275                If an `Expression` instance is passed, this is used as-is.
2276            as_: the SQL code string to parse as the table expression.
2277                If an `Expression` instance is passed, it will be used as-is.
2278            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2279            materialized: set the MATERIALIZED part of the expression.
2280            append: if `True`, add to any existing expressions.
2281                Otherwise, this resets the expressions.
2282            dialect: the dialect used to parse the input expression.
2283            copy: if `False`, modify this expression instance in-place.
2284            opts: other options to use to parse the input expressions.
2285
2286        Returns:
2287            The modified expression.
2288        """
2289        return _apply_cte_builder(
2290            self,
2291            alias,
2292            as_,
2293            recursive=recursive,
2294            materialized=materialized,
2295            append=append,
2296            dialect=dialect,
2297            copy=copy,
2298            **opts,
2299        )

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):
2302class ConditionalInsert(Expression):
2303    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2306class MultitableInserts(Expression):
2307    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2310class OnConflict(Expression):
2311    arg_types = {
2312        "duplicate": False,
2313        "expressions": False,
2314        "action": False,
2315        "conflict_keys": False,
2316        "constraint": False,
2317        "where": False,
2318    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2321class OnCondition(Expression):
2322    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2325class Returning(Expression):
2326    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2330class Introducer(Expression):
2331    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2335class National(Expression):
2336    pass
key = 'national'
class LoadData(Expression):
2339class LoadData(Expression):
2340    arg_types = {
2341        "this": True,
2342        "local": False,
2343        "overwrite": False,
2344        "inpath": True,
2345        "partition": False,
2346        "input_format": False,
2347        "serde": False,
2348    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2351class Partition(Expression):
2352    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2355class PartitionRange(Expression):
2356    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2360class PartitionId(Expression):
2361    pass
key = 'partitionid'
class Fetch(Expression):
2364class Fetch(Expression):
2365    arg_types = {
2366        "direction": False,
2367        "count": False,
2368        "limit_options": False,
2369    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2372class Grant(Expression):
2373    arg_types = {
2374        "privileges": True,
2375        "kind": False,
2376        "securable": True,
2377        "principals": True,
2378        "grant_option": False,
2379    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2382class Group(Expression):
2383    arg_types = {
2384        "expressions": False,
2385        "grouping_sets": False,
2386        "cube": False,
2387        "rollup": False,
2388        "totals": False,
2389        "all": False,
2390    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2393class Cube(Expression):
2394    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2397class Rollup(Expression):
2398    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2401class GroupingSets(Expression):
2402    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2405class Lambda(Expression):
2406    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2409class Limit(Expression):
2410    arg_types = {
2411        "this": False,
2412        "expression": True,
2413        "offset": False,
2414        "limit_options": False,
2415        "expressions": False,
2416    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2419class LimitOptions(Expression):
2420    arg_types = {
2421        "percent": False,
2422        "rows": False,
2423        "with_ties": False,
2424    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2427class Literal(Condition):
2428    arg_types = {"this": True, "is_string": True}
2429
2430    @property
2431    def hashable_args(self) -> t.Any:
2432        return (self.this, self.args.get("is_string"))
2433
2434    @classmethod
2435    def number(cls, number) -> Literal:
2436        return cls(this=str(number), is_string=False)
2437
2438    @classmethod
2439    def string(cls, string) -> Literal:
2440        return cls(this=str(string), is_string=True)
2441
2442    @property
2443    def output_name(self) -> str:
2444        return self.name
2445
2446    def to_py(self) -> int | str | Decimal:
2447        if self.is_number:
2448            try:
2449                return int(self.this)
2450            except ValueError:
2451                return Decimal(self.this)
2452        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2430    @property
2431    def hashable_args(self) -> t.Any:
2432        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2434    @classmethod
2435    def number(cls, number) -> Literal:
2436        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2438    @classmethod
2439    def string(cls, string) -> Literal:
2440        return cls(this=str(string), is_string=True)
output_name: str
2442    @property
2443    def output_name(self) -> str:
2444        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:
2446    def to_py(self) -> int | str | Decimal:
2447        if self.is_number:
2448            try:
2449                return int(self.this)
2450            except ValueError:
2451                return Decimal(self.this)
2452        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2455class Join(Expression):
2456    arg_types = {
2457        "this": True,
2458        "on": False,
2459        "side": False,
2460        "kind": False,
2461        "using": False,
2462        "method": False,
2463        "global": False,
2464        "hint": False,
2465        "match_condition": False,  # Snowflake
2466        "expressions": False,
2467    }
2468
2469    @property
2470    def method(self) -> str:
2471        return self.text("method").upper()
2472
2473    @property
2474    def kind(self) -> str:
2475        return self.text("kind").upper()
2476
2477    @property
2478    def side(self) -> str:
2479        return self.text("side").upper()
2480
2481    @property
2482    def hint(self) -> str:
2483        return self.text("hint").upper()
2484
2485    @property
2486    def alias_or_name(self) -> str:
2487        return self.this.alias_or_name
2488
2489    @property
2490    def is_semi_or_anti_join(self) -> bool:
2491        return self.kind in ("SEMI", "ANTI")
2492
2493    def on(
2494        self,
2495        *expressions: t.Optional[ExpOrStr],
2496        append: bool = True,
2497        dialect: DialectType = None,
2498        copy: bool = True,
2499        **opts,
2500    ) -> Join:
2501        """
2502        Append to or set the ON expressions.
2503
2504        Example:
2505            >>> import sqlglot
2506            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2507            'JOIN x ON y = 1'
2508
2509        Args:
2510            *expressions: the SQL code strings to parse.
2511                If an `Expression` instance is passed, it will be used as-is.
2512                Multiple expressions are combined with an AND operator.
2513            append: if `True`, AND the new expressions to any existing expression.
2514                Otherwise, this resets the expression.
2515            dialect: the dialect used to parse the input expressions.
2516            copy: if `False`, modify this expression instance in-place.
2517            opts: other options to use to parse the input expressions.
2518
2519        Returns:
2520            The modified Join expression.
2521        """
2522        join = _apply_conjunction_builder(
2523            *expressions,
2524            instance=self,
2525            arg="on",
2526            append=append,
2527            dialect=dialect,
2528            copy=copy,
2529            **opts,
2530        )
2531
2532        if join.kind == "CROSS":
2533            join.set("kind", None)
2534
2535        return join
2536
2537    def using(
2538        self,
2539        *expressions: t.Optional[ExpOrStr],
2540        append: bool = True,
2541        dialect: DialectType = None,
2542        copy: bool = True,
2543        **opts,
2544    ) -> Join:
2545        """
2546        Append to or set the USING expressions.
2547
2548        Example:
2549            >>> import sqlglot
2550            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2551            'JOIN x USING (foo, bla)'
2552
2553        Args:
2554            *expressions: the SQL code strings to parse.
2555                If an `Expression` instance is passed, it will be used as-is.
2556            append: if `True`, concatenate the new expressions to the existing "using" list.
2557                Otherwise, this resets the expression.
2558            dialect: the dialect used to parse the input expressions.
2559            copy: if `False`, modify this expression instance in-place.
2560            opts: other options to use to parse the input expressions.
2561
2562        Returns:
2563            The modified Join expression.
2564        """
2565        join = _apply_list_builder(
2566            *expressions,
2567            instance=self,
2568            arg="using",
2569            append=append,
2570            dialect=dialect,
2571            copy=copy,
2572            **opts,
2573        )
2574
2575        if join.kind == "CROSS":
2576            join.set("kind", None)
2577
2578        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
2469    @property
2470    def method(self) -> str:
2471        return self.text("method").upper()
kind: str
2473    @property
2474    def kind(self) -> str:
2475        return self.text("kind").upper()
side: str
2477    @property
2478    def side(self) -> str:
2479        return self.text("side").upper()
hint: str
2481    @property
2482    def hint(self) -> str:
2483        return self.text("hint").upper()
alias_or_name: str
2485    @property
2486    def alias_or_name(self) -> str:
2487        return self.this.alias_or_name
is_semi_or_anti_join: bool
2489    @property
2490    def is_semi_or_anti_join(self) -> bool:
2491        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:
2493    def on(
2494        self,
2495        *expressions: t.Optional[ExpOrStr],
2496        append: bool = True,
2497        dialect: DialectType = None,
2498        copy: bool = True,
2499        **opts,
2500    ) -> Join:
2501        """
2502        Append to or set the ON expressions.
2503
2504        Example:
2505            >>> import sqlglot
2506            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2507            'JOIN x ON y = 1'
2508
2509        Args:
2510            *expressions: the SQL code strings to parse.
2511                If an `Expression` instance is passed, it will be used as-is.
2512                Multiple expressions are combined with an AND operator.
2513            append: if `True`, AND the new expressions to any existing expression.
2514                Otherwise, this resets the expression.
2515            dialect: the dialect used to parse the input expressions.
2516            copy: if `False`, modify this expression instance in-place.
2517            opts: other options to use to parse the input expressions.
2518
2519        Returns:
2520            The modified Join expression.
2521        """
2522        join = _apply_conjunction_builder(
2523            *expressions,
2524            instance=self,
2525            arg="on",
2526            append=append,
2527            dialect=dialect,
2528            copy=copy,
2529            **opts,
2530        )
2531
2532        if join.kind == "CROSS":
2533            join.set("kind", None)
2534
2535        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:
2537    def using(
2538        self,
2539        *expressions: t.Optional[ExpOrStr],
2540        append: bool = True,
2541        dialect: DialectType = None,
2542        copy: bool = True,
2543        **opts,
2544    ) -> Join:
2545        """
2546        Append to or set the USING expressions.
2547
2548        Example:
2549            >>> import sqlglot
2550            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2551            'JOIN x USING (foo, bla)'
2552
2553        Args:
2554            *expressions: the SQL code strings to parse.
2555                If an `Expression` instance is passed, it will be used as-is.
2556            append: if `True`, concatenate the new expressions to the existing "using" list.
2557                Otherwise, this resets the expression.
2558            dialect: the dialect used to parse the input expressions.
2559            copy: if `False`, modify this expression instance in-place.
2560            opts: other options to use to parse the input expressions.
2561
2562        Returns:
2563            The modified Join expression.
2564        """
2565        join = _apply_list_builder(
2566            *expressions,
2567            instance=self,
2568            arg="using",
2569            append=append,
2570            dialect=dialect,
2571            copy=copy,
2572            **opts,
2573        )
2574
2575        if join.kind == "CROSS":
2576            join.set("kind", None)
2577
2578        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):
2581class Lateral(UDTF):
2582    arg_types = {
2583        "this": True,
2584        "view": False,
2585        "outer": False,
2586        "alias": False,
2587        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2588        "ordinality": False,
2589    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2594class TableFromRows(UDTF):
2595    arg_types = {
2596        "this": True,
2597        "alias": False,
2598        "joins": False,
2599        "pivots": False,
2600        "sample": False,
2601    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2604class MatchRecognizeMeasure(Expression):
2605    arg_types = {
2606        "this": True,
2607        "window_frame": False,
2608    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2611class MatchRecognize(Expression):
2612    arg_types = {
2613        "partition_by": False,
2614        "order": False,
2615        "measures": False,
2616        "rows": False,
2617        "after": False,
2618        "pattern": False,
2619        "define": False,
2620        "alias": False,
2621    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2626class Final(Expression):
2627    pass
key = 'final'
class Offset(Expression):
2630class Offset(Expression):
2631    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2634class Order(Expression):
2635    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2639class WithFill(Expression):
2640    arg_types = {
2641        "from": False,
2642        "to": False,
2643        "step": False,
2644        "interpolate": False,
2645    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2650class Cluster(Order):
2651    pass
key = 'cluster'
class Distribute(Order):
2654class Distribute(Order):
2655    pass
key = 'distribute'
class Sort(Order):
2658class Sort(Order):
2659    pass
key = 'sort'
class Ordered(Expression):
2662class Ordered(Expression):
2663    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2664
2665    @property
2666    def name(self) -> str:
2667        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2665    @property
2666    def name(self) -> str:
2667        return self.this.name
key = 'ordered'
class Property(Expression):
2670class Property(Expression):
2671    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2674class GrantPrivilege(Expression):
2675    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2678class GrantPrincipal(Expression):
2679    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2682class AllowedValuesProperty(Expression):
2683    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2686class AlgorithmProperty(Property):
2687    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2690class AutoIncrementProperty(Property):
2691    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2695class AutoRefreshProperty(Property):
2696    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2699class BackupProperty(Property):
2700    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2703class BlockCompressionProperty(Property):
2704    arg_types = {
2705        "autotemp": False,
2706        "always": False,
2707        "default": False,
2708        "manual": False,
2709        "never": False,
2710    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2713class CharacterSetProperty(Property):
2714    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2717class ChecksumProperty(Property):
2718    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2721class CollateProperty(Property):
2722    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2725class CopyGrantsProperty(Property):
2726    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2729class DataBlocksizeProperty(Property):
2730    arg_types = {
2731        "size": False,
2732        "units": False,
2733        "minimum": False,
2734        "maximum": False,
2735        "default": False,
2736    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2739class DataDeletionProperty(Property):
2740    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):
2743class DefinerProperty(Property):
2744    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2747class DistKeyProperty(Property):
2748    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2753class DistributedByProperty(Property):
2754    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):
2757class DistStyleProperty(Property):
2758    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2761class DuplicateKeyProperty(Property):
2762    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2765class EngineProperty(Property):
2766    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2769class HeapProperty(Property):
2770    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2773class ToTableProperty(Property):
2774    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2777class ExecuteAsProperty(Property):
2778    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2781class ExternalProperty(Property):
2782    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2785class FallbackProperty(Property):
2786    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2789class FileFormatProperty(Property):
2790    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2793class CredentialsProperty(Property):
2794    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2797class FreespaceProperty(Property):
2798    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2801class GlobalProperty(Property):
2802    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2805class IcebergProperty(Property):
2806    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2809class InheritsProperty(Property):
2810    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2813class InputModelProperty(Property):
2814    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2817class OutputModelProperty(Property):
2818    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2821class IsolatedLoadingProperty(Property):
2822    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2825class JournalProperty(Property):
2826    arg_types = {
2827        "no": False,
2828        "dual": False,
2829        "before": False,
2830        "local": False,
2831        "after": False,
2832    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2835class LanguageProperty(Property):
2836    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2840class ClusteredByProperty(Property):
2841    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2844class DictProperty(Property):
2845    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2848class DictSubProperty(Property):
2849    pass
key = 'dictsubproperty'
class DictRange(Property):
2852class DictRange(Property):
2853    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2856class DynamicProperty(Property):
2857    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2862class OnCluster(Property):
2863    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2867class EmptyProperty(Property):
2868    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2871class LikeProperty(Property):
2872    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2875class LocationProperty(Property):
2876    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2879class LockProperty(Property):
2880    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2883class LockingProperty(Property):
2884    arg_types = {
2885        "this": False,
2886        "kind": True,
2887        "for_or_in": False,
2888        "lock_type": True,
2889        "override": False,
2890    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2893class LogProperty(Property):
2894    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2897class MaterializedProperty(Property):
2898    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2901class MergeBlockRatioProperty(Property):
2902    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):
2905class NoPrimaryIndexProperty(Property):
2906    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2909class OnProperty(Property):
2910    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2913class OnCommitProperty(Property):
2914    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2917class PartitionedByProperty(Property):
2918    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionByRangeProperty(Property):
2922class PartitionByRangeProperty(Property):
2923    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2927class PartitionByRangePropertyDynamic(Expression):
2928    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):
2932class UniqueKeyProperty(Property):
2933    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2937class PartitionBoundSpec(Expression):
2938    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2939    arg_types = {
2940        "this": False,
2941        "expression": False,
2942        "from_expressions": False,
2943        "to_expressions": False,
2944    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2947class PartitionedOfProperty(Property):
2948    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2949    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2952class StreamingTableProperty(Property):
2953    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2956class RemoteWithConnectionModelProperty(Property):
2957    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2960class ReturnsProperty(Property):
2961    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):
2964class StrictProperty(Property):
2965    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2968class RowFormatProperty(Property):
2969    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2972class RowFormatDelimitedProperty(Property):
2973    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2974    arg_types = {
2975        "fields": False,
2976        "escaped": False,
2977        "collection_items": False,
2978        "map_keys": False,
2979        "lines": False,
2980        "null": False,
2981        "serde": False,
2982    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2985class RowFormatSerdeProperty(Property):
2986    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2990class QueryTransform(Expression):
2991    arg_types = {
2992        "expressions": True,
2993        "command_script": True,
2994        "schema": False,
2995        "row_format_before": False,
2996        "record_writer": False,
2997        "row_format_after": False,
2998        "record_reader": False,
2999    }
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):
3002class SampleProperty(Property):
3003    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3007class SecurityProperty(Property):
3008    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3011class SchemaCommentProperty(Property):
3012    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
3015class SerdeProperties(Property):
3016    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3019class SetProperty(Property):
3020    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3023class SharingProperty(Property):
3024    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3027class SetConfigProperty(Property):
3028    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3031class SettingsProperty(Property):
3032    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3035class SortKeyProperty(Property):
3036    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3039class SqlReadWriteProperty(Property):
3040    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3043class SqlSecurityProperty(Property):
3044    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3047class StabilityProperty(Property):
3048    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3051class StorageHandlerProperty(Property):
3052    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3055class TemporaryProperty(Property):
3056    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3059class SecureProperty(Property):
3060    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3064class Tags(ColumnConstraintKind, Property):
3065    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3068class TransformModelProperty(Property):
3069    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3072class TransientProperty(Property):
3073    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3076class UnloggedProperty(Property):
3077    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3081class UsingTemplateProperty(Property):
3082    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3086class ViewAttributeProperty(Property):
3087    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3090class VolatileProperty(Property):
3091    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3094class WithDataProperty(Property):
3095    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3098class WithJournalTableProperty(Property):
3099    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3102class WithSchemaBindingProperty(Property):
3103    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3106class WithSystemVersioningProperty(Property):
3107    arg_types = {
3108        "on": False,
3109        "this": False,
3110        "data_consistency": False,
3111        "retention_period": False,
3112        "with": True,
3113    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3116class WithProcedureOptions(Property):
3117    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3120class EncodeProperty(Property):
3121    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3124class IncludeProperty(Property):
3125    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3128class ForceProperty(Property):
3129    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3132class Properties(Expression):
3133    arg_types = {"expressions": True}
3134
3135    NAME_TO_PROPERTY = {
3136        "ALGORITHM": AlgorithmProperty,
3137        "AUTO_INCREMENT": AutoIncrementProperty,
3138        "CHARACTER SET": CharacterSetProperty,
3139        "CLUSTERED_BY": ClusteredByProperty,
3140        "COLLATE": CollateProperty,
3141        "COMMENT": SchemaCommentProperty,
3142        "CREDENTIALS": CredentialsProperty,
3143        "DEFINER": DefinerProperty,
3144        "DISTKEY": DistKeyProperty,
3145        "DISTRIBUTED_BY": DistributedByProperty,
3146        "DISTSTYLE": DistStyleProperty,
3147        "ENGINE": EngineProperty,
3148        "EXECUTE AS": ExecuteAsProperty,
3149        "FORMAT": FileFormatProperty,
3150        "LANGUAGE": LanguageProperty,
3151        "LOCATION": LocationProperty,
3152        "LOCK": LockProperty,
3153        "PARTITIONED_BY": PartitionedByProperty,
3154        "RETURNS": ReturnsProperty,
3155        "ROW_FORMAT": RowFormatProperty,
3156        "SORTKEY": SortKeyProperty,
3157        "ENCODE": EncodeProperty,
3158        "INCLUDE": IncludeProperty,
3159    }
3160
3161    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3162
3163    # CREATE property locations
3164    # Form: schema specified
3165    #   create [POST_CREATE]
3166    #     table a [POST_NAME]
3167    #     (b int) [POST_SCHEMA]
3168    #     with ([POST_WITH])
3169    #     index (b) [POST_INDEX]
3170    #
3171    # Form: alias selection
3172    #   create [POST_CREATE]
3173    #     table a [POST_NAME]
3174    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3175    #     index (c) [POST_INDEX]
3176    class Location(AutoName):
3177        POST_CREATE = auto()
3178        POST_NAME = auto()
3179        POST_SCHEMA = auto()
3180        POST_WITH = auto()
3181        POST_ALIAS = auto()
3182        POST_EXPRESSION = auto()
3183        POST_INDEX = auto()
3184        UNSUPPORTED = auto()
3185
3186    @classmethod
3187    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3188        expressions = []
3189        for key, value in properties_dict.items():
3190            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3191            if property_cls:
3192                expressions.append(property_cls(this=convert(value)))
3193            else:
3194                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3195
3196        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:
3186    @classmethod
3187    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3188        expressions = []
3189        for key, value in properties_dict.items():
3190            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3191            if property_cls:
3192                expressions.append(property_cls(this=convert(value)))
3193            else:
3194                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3195
3196        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3176    class Location(AutoName):
3177        POST_CREATE = auto()
3178        POST_NAME = auto()
3179        POST_SCHEMA = auto()
3180        POST_WITH = auto()
3181        POST_ALIAS = auto()
3182        POST_EXPRESSION = auto()
3183        POST_INDEX = auto()
3184        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):
3199class Qualify(Expression):
3200    pass
key = 'qualify'
class InputOutputFormat(Expression):
3203class InputOutputFormat(Expression):
3204    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3208class Return(Expression):
3209    pass
key = 'return'
class Reference(Expression):
3212class Reference(Expression):
3213    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3216class Tuple(Expression):
3217    arg_types = {"expressions": False}
3218
3219    def isin(
3220        self,
3221        *expressions: t.Any,
3222        query: t.Optional[ExpOrStr] = None,
3223        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3224        copy: bool = True,
3225        **opts,
3226    ) -> In:
3227        return In(
3228            this=maybe_copy(self, copy),
3229            expressions=[convert(e, copy=copy) for e in expressions],
3230            query=maybe_parse(query, copy=copy, **opts) if query else None,
3231            unnest=(
3232                Unnest(
3233                    expressions=[
3234                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3235                        for e in ensure_list(unnest)
3236                    ]
3237                )
3238                if unnest
3239                else None
3240            ),
3241        )
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:
3219    def isin(
3220        self,
3221        *expressions: t.Any,
3222        query: t.Optional[ExpOrStr] = None,
3223        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3224        copy: bool = True,
3225        **opts,
3226    ) -> In:
3227        return In(
3228            this=maybe_copy(self, copy),
3229            expressions=[convert(e, copy=copy) for e in expressions],
3230            query=maybe_parse(query, copy=copy, **opts) if query else None,
3231            unnest=(
3232                Unnest(
3233                    expressions=[
3234                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3235                        for e in ensure_list(unnest)
3236                    ]
3237                )
3238                if unnest
3239                else None
3240            ),
3241        )
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):
3272class QueryOption(Expression):
3273    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3277class WithTableHint(Expression):
3278    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3282class IndexTableHint(Expression):
3283    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3287class HistoricalData(Expression):
3288    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3292class Put(Expression):
3293    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Table(Expression):
3296class Table(Expression):
3297    arg_types = {
3298        "this": False,
3299        "alias": False,
3300        "db": False,
3301        "catalog": False,
3302        "laterals": False,
3303        "joins": False,
3304        "pivots": False,
3305        "hints": False,
3306        "system_time": False,
3307        "version": False,
3308        "format": False,
3309        "pattern": False,
3310        "ordinality": False,
3311        "when": False,
3312        "only": False,
3313        "partition": False,
3314        "changes": False,
3315        "rows_from": False,
3316        "sample": False,
3317    }
3318
3319    @property
3320    def name(self) -> str:
3321        if not self.this or isinstance(self.this, Func):
3322            return ""
3323        return self.this.name
3324
3325    @property
3326    def db(self) -> str:
3327        return self.text("db")
3328
3329    @property
3330    def catalog(self) -> str:
3331        return self.text("catalog")
3332
3333    @property
3334    def selects(self) -> t.List[Expression]:
3335        return []
3336
3337    @property
3338    def named_selects(self) -> t.List[str]:
3339        return []
3340
3341    @property
3342    def parts(self) -> t.List[Expression]:
3343        """Return the parts of a table in order catalog, db, table."""
3344        parts: t.List[Expression] = []
3345
3346        for arg in ("catalog", "db", "this"):
3347            part = self.args.get(arg)
3348
3349            if isinstance(part, Dot):
3350                parts.extend(part.flatten())
3351            elif isinstance(part, Expression):
3352                parts.append(part)
3353
3354        return parts
3355
3356    def to_column(self, copy: bool = True) -> Expression:
3357        parts = self.parts
3358        last_part = parts[-1]
3359
3360        if isinstance(last_part, Identifier):
3361            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3362        else:
3363            # This branch will be reached if a function or array is wrapped in a `Table`
3364            col = last_part
3365
3366        alias = self.args.get("alias")
3367        if alias:
3368            col = alias_(col, alias.this, copy=copy)
3369
3370        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
3319    @property
3320    def name(self) -> str:
3321        if not self.this or isinstance(self.this, Func):
3322            return ""
3323        return self.this.name
db: str
3325    @property
3326    def db(self) -> str:
3327        return self.text("db")
catalog: str
3329    @property
3330    def catalog(self) -> str:
3331        return self.text("catalog")
selects: List[Expression]
3333    @property
3334    def selects(self) -> t.List[Expression]:
3335        return []
named_selects: List[str]
3337    @property
3338    def named_selects(self) -> t.List[str]:
3339        return []
parts: List[Expression]
3341    @property
3342    def parts(self) -> t.List[Expression]:
3343        """Return the parts of a table in order catalog, db, table."""
3344        parts: t.List[Expression] = []
3345
3346        for arg in ("catalog", "db", "this"):
3347            part = self.args.get(arg)
3348
3349            if isinstance(part, Dot):
3350                parts.extend(part.flatten())
3351            elif isinstance(part, Expression):
3352                parts.append(part)
3353
3354        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3356    def to_column(self, copy: bool = True) -> Expression:
3357        parts = self.parts
3358        last_part = parts[-1]
3359
3360        if isinstance(last_part, Identifier):
3361            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3362        else:
3363            # This branch will be reached if a function or array is wrapped in a `Table`
3364            col = last_part
3365
3366        alias = self.args.get("alias")
3367        if alias:
3368            col = alias_(col, alias.this, copy=copy)
3369
3370        return col
key = 'table'
class SetOperation(Query):
3373class SetOperation(Query):
3374    arg_types = {
3375        "with": False,
3376        "this": True,
3377        "expression": True,
3378        "distinct": False,
3379        "by_name": False,
3380        "side": False,
3381        "kind": False,
3382        "on": False,
3383        **QUERY_MODIFIERS,
3384    }
3385
3386    def select(
3387        self: S,
3388        *expressions: t.Optional[ExpOrStr],
3389        append: bool = True,
3390        dialect: DialectType = None,
3391        copy: bool = True,
3392        **opts,
3393    ) -> S:
3394        this = maybe_copy(self, copy)
3395        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3396        this.expression.unnest().select(
3397            *expressions, append=append, dialect=dialect, copy=False, **opts
3398        )
3399        return this
3400
3401    @property
3402    def named_selects(self) -> t.List[str]:
3403        return self.this.unnest().named_selects
3404
3405    @property
3406    def is_star(self) -> bool:
3407        return self.this.is_star or self.expression.is_star
3408
3409    @property
3410    def selects(self) -> t.List[Expression]:
3411        return self.this.unnest().selects
3412
3413    @property
3414    def left(self) -> Query:
3415        return self.this
3416
3417    @property
3418    def right(self) -> Query:
3419        return self.expression
3420
3421    @property
3422    def kind(self) -> str:
3423        return self.text("kind").upper()
3424
3425    @property
3426    def side(self) -> str:
3427        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:
3386    def select(
3387        self: S,
3388        *expressions: t.Optional[ExpOrStr],
3389        append: bool = True,
3390        dialect: DialectType = None,
3391        copy: bool = True,
3392        **opts,
3393    ) -> S:
3394        this = maybe_copy(self, copy)
3395        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3396        this.expression.unnest().select(
3397            *expressions, append=append, dialect=dialect, copy=False, **opts
3398        )
3399        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]
3401    @property
3402    def named_selects(self) -> t.List[str]:
3403        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3405    @property
3406    def is_star(self) -> bool:
3407        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3409    @property
3410    def selects(self) -> t.List[Expression]:
3411        return self.this.unnest().selects

Returns the query's projections.

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

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:
3486    def set_(
3487        self,
3488        *expressions: ExpOrStr,
3489        append: bool = True,
3490        dialect: DialectType = None,
3491        copy: bool = True,
3492        **opts,
3493    ) -> Update:
3494        """
3495        Append to or set the SET expressions.
3496
3497        Example:
3498            >>> Update().table("my_table").set_("x = 1").sql()
3499            'UPDATE my_table SET x = 1'
3500
3501        Args:
3502            *expressions: the SQL code strings to parse.
3503                If `Expression` instance(s) are passed, they will be used as-is.
3504                Multiple expressions are combined with a comma.
3505            append: if `True`, add the new expressions to any existing SET expressions.
3506                Otherwise, this resets the expressions.
3507            dialect: the dialect used to parse the input expressions.
3508            copy: if `False`, modify this expression instance in-place.
3509            opts: other options to use to parse the input expressions.
3510        """
3511        return _apply_list_builder(
3512            *expressions,
3513            instance=self,
3514            arg="expressions",
3515            append=append,
3516            into=Expression,
3517            prefix=None,
3518            dialect=dialect,
3519            copy=copy,
3520            **opts,
3521        )

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:
3523    def where(
3524        self,
3525        *expressions: t.Optional[ExpOrStr],
3526        append: bool = True,
3527        dialect: DialectType = None,
3528        copy: bool = True,
3529        **opts,
3530    ) -> Select:
3531        """
3532        Append to or set the WHERE expressions.
3533
3534        Example:
3535            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3536            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3537
3538        Args:
3539            *expressions: the SQL code strings to parse.
3540                If an `Expression` instance is passed, it will be used as-is.
3541                Multiple expressions are combined with an AND operator.
3542            append: if `True`, AND the new expressions to any existing expression.
3543                Otherwise, this resets the expression.
3544            dialect: the dialect used to parse the input expressions.
3545            copy: if `False`, modify this expression instance in-place.
3546            opts: other options to use to parse the input expressions.
3547
3548        Returns:
3549            Select: the modified expression.
3550        """
3551        return _apply_conjunction_builder(
3552            *expressions,
3553            instance=self,
3554            arg="where",
3555            append=append,
3556            into=Where,
3557            dialect=dialect,
3558            copy=copy,
3559            **opts,
3560        )

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:
3562    def from_(
3563        self,
3564        expression: t.Optional[ExpOrStr] = None,
3565        dialect: DialectType = None,
3566        copy: bool = True,
3567        **opts,
3568    ) -> Update:
3569        """
3570        Set the FROM expression.
3571
3572        Example:
3573            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3574            'UPDATE my_table SET x = 1 FROM baz'
3575
3576        Args:
3577            expression : the SQL code strings to parse.
3578                If a `From` instance is passed, this is used as-is.
3579                If another `Expression` instance is passed, it will be wrapped in a `From`.
3580                If nothing is passed in then a from is not applied to the expression
3581            dialect: the dialect used to parse the input expression.
3582            copy: if `False`, modify this expression instance in-place.
3583            opts: other options to use to parse the input expressions.
3584
3585        Returns:
3586            The modified Update expression.
3587        """
3588        if not expression:
3589            return maybe_copy(self, copy)
3590
3591        return _apply_builder(
3592            expression=expression,
3593            instance=self,
3594            arg="from",
3595            into=From,
3596            prefix="FROM",
3597            dialect=dialect,
3598            copy=copy,
3599            **opts,
3600        )

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:
3602    def with_(
3603        self,
3604        alias: ExpOrStr,
3605        as_: ExpOrStr,
3606        recursive: t.Optional[bool] = None,
3607        materialized: t.Optional[bool] = None,
3608        append: bool = True,
3609        dialect: DialectType = None,
3610        copy: bool = True,
3611        **opts,
3612    ) -> Update:
3613        """
3614        Append to or set the common table expressions.
3615
3616        Example:
3617            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3618            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3619
3620        Args:
3621            alias: the SQL code string to parse as the table name.
3622                If an `Expression` instance is passed, this is used as-is.
3623            as_: the SQL code string to parse as the table expression.
3624                If an `Expression` instance is passed, it will be used as-is.
3625            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3626            materialized: set the MATERIALIZED part of the expression.
3627            append: if `True`, add to any existing expressions.
3628                Otherwise, this resets the expressions.
3629            dialect: the dialect used to parse the input expression.
3630            copy: if `False`, modify this expression instance in-place.
3631            opts: other options to use to parse the input expressions.
3632
3633        Returns:
3634            The modified expression.
3635        """
3636        return _apply_cte_builder(
3637            self,
3638            alias,
3639            as_,
3640            recursive=recursive,
3641            materialized=materialized,
3642            append=append,
3643            dialect=dialect,
3644            copy=copy,
3645            **opts,
3646        )

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

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:
3726    def group_by(
3727        self,
3728        *expressions: t.Optional[ExpOrStr],
3729        append: bool = True,
3730        dialect: DialectType = None,
3731        copy: bool = True,
3732        **opts,
3733    ) -> Select:
3734        """
3735        Set the GROUP BY expression.
3736
3737        Example:
3738            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3739            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3740
3741        Args:
3742            *expressions: the SQL code strings to parse.
3743                If a `Group` instance is passed, this is used as-is.
3744                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3745                If nothing is passed in then a group by is not applied to the expression
3746            append: if `True`, add to any existing expressions.
3747                Otherwise, this flattens all the `Group` expression into a single expression.
3748            dialect: the dialect used to parse the input expression.
3749            copy: if `False`, modify this expression instance in-place.
3750            opts: other options to use to parse the input expressions.
3751
3752        Returns:
3753            The modified Select expression.
3754        """
3755        if not expressions:
3756            return self if not copy else self.copy()
3757
3758        return _apply_child_list_builder(
3759            *expressions,
3760            instance=self,
3761            arg="group",
3762            append=append,
3763            copy=copy,
3764            prefix="GROUP BY",
3765            into=Group,
3766            dialect=dialect,
3767            **opts,
3768        )

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:
3770    def sort_by(
3771        self,
3772        *expressions: t.Optional[ExpOrStr],
3773        append: bool = True,
3774        dialect: DialectType = None,
3775        copy: bool = True,
3776        **opts,
3777    ) -> Select:
3778        """
3779        Set the SORT BY expression.
3780
3781        Example:
3782            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3783            'SELECT x FROM tbl SORT BY x DESC'
3784
3785        Args:
3786            *expressions: the SQL code strings to parse.
3787                If a `Group` instance is passed, this is used as-is.
3788                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3789            append: if `True`, add to any existing expressions.
3790                Otherwise, this flattens all the `Order` expression into a single expression.
3791            dialect: the dialect used to parse the input expression.
3792            copy: if `False`, modify this expression instance in-place.
3793            opts: other options to use to parse the input expressions.
3794
3795        Returns:
3796            The modified Select expression.
3797        """
3798        return _apply_child_list_builder(
3799            *expressions,
3800            instance=self,
3801            arg="sort",
3802            append=append,
3803            copy=copy,
3804            prefix="SORT BY",
3805            into=Sort,
3806            dialect=dialect,
3807            **opts,
3808        )

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:
3810    def cluster_by(
3811        self,
3812        *expressions: t.Optional[ExpOrStr],
3813        append: bool = True,
3814        dialect: DialectType = None,
3815        copy: bool = True,
3816        **opts,
3817    ) -> Select:
3818        """
3819        Set the CLUSTER BY expression.
3820
3821        Example:
3822            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3823            'SELECT x FROM tbl CLUSTER BY x DESC'
3824
3825        Args:
3826            *expressions: the SQL code strings to parse.
3827                If a `Group` instance is passed, this is used as-is.
3828                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3829            append: if `True`, add to any existing expressions.
3830                Otherwise, this flattens all the `Order` expression into a single expression.
3831            dialect: the dialect used to parse the input expression.
3832            copy: if `False`, modify this expression instance in-place.
3833            opts: other options to use to parse the input expressions.
3834
3835        Returns:
3836            The modified Select expression.
3837        """
3838        return _apply_child_list_builder(
3839            *expressions,
3840            instance=self,
3841            arg="cluster",
3842            append=append,
3843            copy=copy,
3844            prefix="CLUSTER BY",
3845            into=Cluster,
3846            dialect=dialect,
3847            **opts,
3848        )

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:
3850    def select(
3851        self,
3852        *expressions: t.Optional[ExpOrStr],
3853        append: bool = True,
3854        dialect: DialectType = None,
3855        copy: bool = True,
3856        **opts,
3857    ) -> Select:
3858        return _apply_list_builder(
3859            *expressions,
3860            instance=self,
3861            arg="expressions",
3862            append=append,
3863            dialect=dialect,
3864            into=Expression,
3865            copy=copy,
3866            **opts,
3867        )

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:
3869    def lateral(
3870        self,
3871        *expressions: t.Optional[ExpOrStr],
3872        append: bool = True,
3873        dialect: DialectType = None,
3874        copy: bool = True,
3875        **opts,
3876    ) -> Select:
3877        """
3878        Append to or set the LATERAL expressions.
3879
3880        Example:
3881            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3882            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3883
3884        Args:
3885            *expressions: the SQL code strings to parse.
3886                If an `Expression` instance is passed, it will be used as-is.
3887            append: if `True`, add to any existing expressions.
3888                Otherwise, this resets the expressions.
3889            dialect: the dialect used to parse the input expressions.
3890            copy: if `False`, modify this expression instance in-place.
3891            opts: other options to use to parse the input expressions.
3892
3893        Returns:
3894            The modified Select expression.
3895        """
3896        return _apply_list_builder(
3897            *expressions,
3898            instance=self,
3899            arg="laterals",
3900            append=append,
3901            into=Lateral,
3902            prefix="LATERAL VIEW",
3903            dialect=dialect,
3904            copy=copy,
3905            **opts,
3906        )

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

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:
4006    def where(
4007        self,
4008        *expressions: t.Optional[ExpOrStr],
4009        append: bool = True,
4010        dialect: DialectType = None,
4011        copy: bool = True,
4012        **opts,
4013    ) -> Select:
4014        """
4015        Append to or set the WHERE expressions.
4016
4017        Example:
4018            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
4019            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
4020
4021        Args:
4022            *expressions: the SQL code strings to parse.
4023                If an `Expression` instance is passed, it will be used as-is.
4024                Multiple expressions are combined with an AND operator.
4025            append: if `True`, AND the new expressions to any existing expression.
4026                Otherwise, this resets the expression.
4027            dialect: the dialect used to parse the input expressions.
4028            copy: if `False`, modify this expression instance in-place.
4029            opts: other options to use to parse the input expressions.
4030
4031        Returns:
4032            Select: the modified expression.
4033        """
4034        return _apply_conjunction_builder(
4035            *expressions,
4036            instance=self,
4037            arg="where",
4038            append=append,
4039            into=Where,
4040            dialect=dialect,
4041            copy=copy,
4042            **opts,
4043        )

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:
4045    def having(
4046        self,
4047        *expressions: t.Optional[ExpOrStr],
4048        append: bool = True,
4049        dialect: DialectType = None,
4050        copy: bool = True,
4051        **opts,
4052    ) -> Select:
4053        """
4054        Append to or set the HAVING expressions.
4055
4056        Example:
4057            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4058            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4059
4060        Args:
4061            *expressions: the SQL code strings to parse.
4062                If an `Expression` instance is passed, it will be used as-is.
4063                Multiple expressions are combined with an AND operator.
4064            append: if `True`, AND the new expressions to any existing expression.
4065                Otherwise, this resets the expression.
4066            dialect: the dialect used to parse the input expressions.
4067            copy: if `False`, modify this expression instance in-place.
4068            opts: other options to use to parse the input expressions.
4069
4070        Returns:
4071            The modified Select expression.
4072        """
4073        return _apply_conjunction_builder(
4074            *expressions,
4075            instance=self,
4076            arg="having",
4077            append=append,
4078            into=Having,
4079            dialect=dialect,
4080            copy=copy,
4081            **opts,
4082        )

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

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:
4185    def lock(self, update: bool = True, copy: bool = True) -> Select:
4186        """
4187        Set the locking read mode for this expression.
4188
4189        Examples:
4190            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4191            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4192
4193            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4194            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4195
4196        Args:
4197            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4198            copy: if `False`, modify this expression instance in-place.
4199
4200        Returns:
4201            The modified expression.
4202        """
4203        inst = maybe_copy(self, copy)
4204        inst.set("locks", [Lock(update=update)])
4205
4206        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:
4208    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4209        """
4210        Set hints for this expression.
4211
4212        Examples:
4213            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4214            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4215
4216        Args:
4217            hints: The SQL code strings to parse as the hints.
4218                If an `Expression` instance is passed, it will be used as-is.
4219            dialect: The dialect used to parse the hints.
4220            copy: If `False`, modify this expression instance in-place.
4221
4222        Returns:
4223            The modified expression.
4224        """
4225        inst = maybe_copy(self, copy)
4226        inst.set(
4227            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4228        )
4229
4230        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]
4232    @property
4233    def named_selects(self) -> t.List[str]:
4234        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
4236    @property
4237    def is_star(self) -> bool:
4238        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4240    @property
4241    def selects(self) -> t.List[Expression]:
4242        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4248class Subquery(DerivedTable, Query):
4249    arg_types = {
4250        "this": True,
4251        "alias": False,
4252        "with": False,
4253        **QUERY_MODIFIERS,
4254    }
4255
4256    def unnest(self):
4257        """Returns the first non subquery."""
4258        expression = self
4259        while isinstance(expression, Subquery):
4260            expression = expression.this
4261        return expression
4262
4263    def unwrap(self) -> Subquery:
4264        expression = self
4265        while expression.same_parent and expression.is_wrapper:
4266            expression = t.cast(Subquery, expression.parent)
4267        return expression
4268
4269    def select(
4270        self,
4271        *expressions: t.Optional[ExpOrStr],
4272        append: bool = True,
4273        dialect: DialectType = None,
4274        copy: bool = True,
4275        **opts,
4276    ) -> Subquery:
4277        this = maybe_copy(self, copy)
4278        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4279        return this
4280
4281    @property
4282    def is_wrapper(self) -> bool:
4283        """
4284        Whether this Subquery acts as a simple wrapper around another expression.
4285
4286        SELECT * FROM (((SELECT * FROM t)))
4287                      ^
4288                      This corresponds to a "wrapper" Subquery node
4289        """
4290        return all(v is None for k, v in self.args.items() if k != "this")
4291
4292    @property
4293    def is_star(self) -> bool:
4294        return self.this.is_star
4295
4296    @property
4297    def output_name(self) -> str:
4298        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):
4256    def unnest(self):
4257        """Returns the first non subquery."""
4258        expression = self
4259        while isinstance(expression, Subquery):
4260            expression = expression.this
4261        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4263    def unwrap(self) -> Subquery:
4264        expression = self
4265        while expression.same_parent and expression.is_wrapper:
4266            expression = t.cast(Subquery, expression.parent)
4267        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:
4269    def select(
4270        self,
4271        *expressions: t.Optional[ExpOrStr],
4272        append: bool = True,
4273        dialect: DialectType = None,
4274        copy: bool = True,
4275        **opts,
4276    ) -> Subquery:
4277        this = maybe_copy(self, copy)
4278        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4279        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
4281    @property
4282    def is_wrapper(self) -> bool:
4283        """
4284        Whether this Subquery acts as a simple wrapper around another expression.
4285
4286        SELECT * FROM (((SELECT * FROM t)))
4287                      ^
4288                      This corresponds to a "wrapper" Subquery node
4289        """
4290        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
4292    @property
4293    def is_star(self) -> bool:
4294        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4296    @property
4297    def output_name(self) -> str:
4298        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):
4301class TableSample(Expression):
4302    arg_types = {
4303        "expressions": False,
4304        "method": False,
4305        "bucket_numerator": False,
4306        "bucket_denominator": False,
4307        "bucket_field": False,
4308        "percent": False,
4309        "rows": False,
4310        "size": False,
4311        "seed": False,
4312    }
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):
4315class Tag(Expression):
4316    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4317
4318    arg_types = {
4319        "this": False,
4320        "prefix": False,
4321        "postfix": False,
4322    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4327class Pivot(Expression):
4328    arg_types = {
4329        "this": False,
4330        "alias": False,
4331        "expressions": False,
4332        "fields": False,
4333        "unpivot": False,
4334        "using": False,
4335        "group": False,
4336        "columns": False,
4337        "include_nulls": False,
4338        "default_on_null": False,
4339        "into": False,
4340    }
4341
4342    @property
4343    def unpivot(self) -> bool:
4344        return bool(self.args.get("unpivot"))
4345
4346    @property
4347    def fields(self) -> t.List[Expression]:
4348        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
4342    @property
4343    def unpivot(self) -> bool:
4344        return bool(self.args.get("unpivot"))
fields: List[Expression]
4346    @property
4347    def fields(self) -> t.List[Expression]:
4348        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4353class UnpivotColumns(Expression):
4354    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4357class Window(Condition):
4358    arg_types = {
4359        "this": True,
4360        "partition_by": False,
4361        "order": False,
4362        "spec": False,
4363        "alias": False,
4364        "over": False,
4365        "first": False,
4366    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4369class WindowSpec(Expression):
4370    arg_types = {
4371        "kind": False,
4372        "start": False,
4373        "start_side": False,
4374        "end": False,
4375        "end_side": False,
4376    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4379class PreWhere(Expression):
4380    pass
key = 'prewhere'
class Where(Expression):
4383class Where(Expression):
4384    pass
key = 'where'
class Star(Expression):
4387class Star(Expression):
4388    arg_types = {"except": False, "replace": False, "rename": False}
4389
4390    @property
4391    def name(self) -> str:
4392        return "*"
4393
4394    @property
4395    def output_name(self) -> str:
4396        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4390    @property
4391    def name(self) -> str:
4392        return "*"
output_name: str
4394    @property
4395    def output_name(self) -> str:
4396        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):
4399class Parameter(Condition):
4400    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4403class SessionParameter(Condition):
4404    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4407class Placeholder(Condition):
4408    arg_types = {"this": False, "kind": False}
4409
4410    @property
4411    def name(self) -> str:
4412        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4410    @property
4411    def name(self) -> str:
4412        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4415class Null(Condition):
4416    arg_types: t.Dict[str, t.Any] = {}
4417
4418    @property
4419    def name(self) -> str:
4420        return "NULL"
4421
4422    def to_py(self) -> Lit[None]:
4423        return None
arg_types: Dict[str, Any] = {}
name: str
4418    @property
4419    def name(self) -> str:
4420        return "NULL"
def to_py(self) -> Literal[None]:
4422    def to_py(self) -> Lit[None]:
4423        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4426class Boolean(Condition):
4427    def to_py(self) -> bool:
4428        return self.this
def to_py(self) -> bool:
4427    def to_py(self) -> bool:
4428        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4431class DataTypeParam(Expression):
4432    arg_types = {"this": True, "expression": False}
4433
4434    @property
4435    def name(self) -> str:
4436        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4434    @property
4435    def name(self) -> str:
4436        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4441class DataType(Expression):
4442    arg_types = {
4443        "this": True,
4444        "expressions": False,
4445        "nested": False,
4446        "values": False,
4447        "prefix": False,
4448        "kind": False,
4449        "nullable": False,
4450    }
4451
4452    class Type(AutoName):
4453        ARRAY = auto()
4454        AGGREGATEFUNCTION = auto()
4455        SIMPLEAGGREGATEFUNCTION = auto()
4456        BIGDECIMAL = auto()
4457        BIGINT = auto()
4458        BIGSERIAL = auto()
4459        BINARY = auto()
4460        BIT = auto()
4461        BLOB = auto()
4462        BOOLEAN = auto()
4463        BPCHAR = auto()
4464        CHAR = auto()
4465        DATE = auto()
4466        DATE32 = auto()
4467        DATEMULTIRANGE = auto()
4468        DATERANGE = auto()
4469        DATETIME = auto()
4470        DATETIME2 = auto()
4471        DATETIME64 = auto()
4472        DECIMAL = auto()
4473        DECIMAL32 = auto()
4474        DECIMAL64 = auto()
4475        DECIMAL128 = auto()
4476        DECIMAL256 = auto()
4477        DOUBLE = auto()
4478        DYNAMIC = auto()
4479        ENUM = auto()
4480        ENUM8 = auto()
4481        ENUM16 = auto()
4482        FIXEDSTRING = auto()
4483        FLOAT = auto()
4484        GEOGRAPHY = auto()
4485        GEOMETRY = auto()
4486        POINT = auto()
4487        RING = auto()
4488        LINESTRING = auto()
4489        MULTILINESTRING = auto()
4490        POLYGON = auto()
4491        MULTIPOLYGON = auto()
4492        HLLSKETCH = auto()
4493        HSTORE = auto()
4494        IMAGE = auto()
4495        INET = auto()
4496        INT = auto()
4497        INT128 = auto()
4498        INT256 = auto()
4499        INT4MULTIRANGE = auto()
4500        INT4RANGE = auto()
4501        INT8MULTIRANGE = auto()
4502        INT8RANGE = auto()
4503        INTERVAL = auto()
4504        IPADDRESS = auto()
4505        IPPREFIX = auto()
4506        IPV4 = auto()
4507        IPV6 = auto()
4508        JSON = auto()
4509        JSONB = auto()
4510        LIST = auto()
4511        LONGBLOB = auto()
4512        LONGTEXT = auto()
4513        LOWCARDINALITY = auto()
4514        MAP = auto()
4515        MEDIUMBLOB = auto()
4516        MEDIUMINT = auto()
4517        MEDIUMTEXT = auto()
4518        MONEY = auto()
4519        NAME = auto()
4520        NCHAR = auto()
4521        NESTED = auto()
4522        NULL = auto()
4523        NUMMULTIRANGE = auto()
4524        NUMRANGE = auto()
4525        NVARCHAR = auto()
4526        OBJECT = auto()
4527        RANGE = auto()
4528        ROWVERSION = auto()
4529        SERIAL = auto()
4530        SET = auto()
4531        SMALLDATETIME = auto()
4532        SMALLINT = auto()
4533        SMALLMONEY = auto()
4534        SMALLSERIAL = auto()
4535        STRUCT = auto()
4536        SUPER = auto()
4537        TEXT = auto()
4538        TINYBLOB = auto()
4539        TINYTEXT = auto()
4540        TIME = auto()
4541        TIMETZ = auto()
4542        TIMESTAMP = auto()
4543        TIMESTAMPNTZ = auto()
4544        TIMESTAMPLTZ = auto()
4545        TIMESTAMPTZ = auto()
4546        TIMESTAMP_S = auto()
4547        TIMESTAMP_MS = auto()
4548        TIMESTAMP_NS = auto()
4549        TINYINT = auto()
4550        TSMULTIRANGE = auto()
4551        TSRANGE = auto()
4552        TSTZMULTIRANGE = auto()
4553        TSTZRANGE = auto()
4554        UBIGINT = auto()
4555        UINT = auto()
4556        UINT128 = auto()
4557        UINT256 = auto()
4558        UMEDIUMINT = auto()
4559        UDECIMAL = auto()
4560        UDOUBLE = auto()
4561        UNION = auto()
4562        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4563        USERDEFINED = "USER-DEFINED"
4564        USMALLINT = auto()
4565        UTINYINT = auto()
4566        UUID = auto()
4567        VARBINARY = auto()
4568        VARCHAR = auto()
4569        VARIANT = auto()
4570        VECTOR = auto()
4571        XML = auto()
4572        YEAR = auto()
4573        TDIGEST = auto()
4574
4575    STRUCT_TYPES = {
4576        Type.NESTED,
4577        Type.OBJECT,
4578        Type.STRUCT,
4579        Type.UNION,
4580    }
4581
4582    ARRAY_TYPES = {
4583        Type.ARRAY,
4584        Type.LIST,
4585    }
4586
4587    NESTED_TYPES = {
4588        *STRUCT_TYPES,
4589        *ARRAY_TYPES,
4590        Type.MAP,
4591    }
4592
4593    TEXT_TYPES = {
4594        Type.CHAR,
4595        Type.NCHAR,
4596        Type.NVARCHAR,
4597        Type.TEXT,
4598        Type.VARCHAR,
4599        Type.NAME,
4600    }
4601
4602    SIGNED_INTEGER_TYPES = {
4603        Type.BIGINT,
4604        Type.INT,
4605        Type.INT128,
4606        Type.INT256,
4607        Type.MEDIUMINT,
4608        Type.SMALLINT,
4609        Type.TINYINT,
4610    }
4611
4612    UNSIGNED_INTEGER_TYPES = {
4613        Type.UBIGINT,
4614        Type.UINT,
4615        Type.UINT128,
4616        Type.UINT256,
4617        Type.UMEDIUMINT,
4618        Type.USMALLINT,
4619        Type.UTINYINT,
4620    }
4621
4622    INTEGER_TYPES = {
4623        *SIGNED_INTEGER_TYPES,
4624        *UNSIGNED_INTEGER_TYPES,
4625        Type.BIT,
4626    }
4627
4628    FLOAT_TYPES = {
4629        Type.DOUBLE,
4630        Type.FLOAT,
4631    }
4632
4633    REAL_TYPES = {
4634        *FLOAT_TYPES,
4635        Type.BIGDECIMAL,
4636        Type.DECIMAL,
4637        Type.DECIMAL32,
4638        Type.DECIMAL64,
4639        Type.DECIMAL128,
4640        Type.DECIMAL256,
4641        Type.MONEY,
4642        Type.SMALLMONEY,
4643        Type.UDECIMAL,
4644        Type.UDOUBLE,
4645    }
4646
4647    NUMERIC_TYPES = {
4648        *INTEGER_TYPES,
4649        *REAL_TYPES,
4650    }
4651
4652    TEMPORAL_TYPES = {
4653        Type.DATE,
4654        Type.DATE32,
4655        Type.DATETIME,
4656        Type.DATETIME2,
4657        Type.DATETIME64,
4658        Type.SMALLDATETIME,
4659        Type.TIME,
4660        Type.TIMESTAMP,
4661        Type.TIMESTAMPNTZ,
4662        Type.TIMESTAMPLTZ,
4663        Type.TIMESTAMPTZ,
4664        Type.TIMESTAMP_MS,
4665        Type.TIMESTAMP_NS,
4666        Type.TIMESTAMP_S,
4667        Type.TIMETZ,
4668    }
4669
4670    @classmethod
4671    def build(
4672        cls,
4673        dtype: DATA_TYPE,
4674        dialect: DialectType = None,
4675        udt: bool = False,
4676        copy: bool = True,
4677        **kwargs,
4678    ) -> DataType:
4679        """
4680        Constructs a DataType object.
4681
4682        Args:
4683            dtype: the data type of interest.
4684            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4685            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4686                DataType, thus creating a user-defined type.
4687            copy: whether to copy the data type.
4688            kwargs: additional arguments to pass in the constructor of DataType.
4689
4690        Returns:
4691            The constructed DataType object.
4692        """
4693        from sqlglot import parse_one
4694
4695        if isinstance(dtype, str):
4696            if dtype.upper() == "UNKNOWN":
4697                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4698
4699            try:
4700                data_type_exp = parse_one(
4701                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4702                )
4703            except ParseError:
4704                if udt:
4705                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4706                raise
4707        elif isinstance(dtype, DataType.Type):
4708            data_type_exp = DataType(this=dtype)
4709        elif isinstance(dtype, DataType):
4710            return maybe_copy(dtype, copy)
4711        else:
4712            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4713
4714        return DataType(**{**data_type_exp.args, **kwargs})
4715
4716    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4717        """
4718        Checks whether this DataType matches one of the provided data types. Nested types or precision
4719        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4720
4721        Args:
4722            dtypes: the data types to compare this DataType to.
4723            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4724                If false, it means that NULLABLE<INT> is equivalent to INT.
4725
4726        Returns:
4727            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4728        """
4729        self_is_nullable = self.args.get("nullable")
4730        for dtype in dtypes:
4731            other_type = DataType.build(dtype, copy=False, udt=True)
4732            other_is_nullable = other_type.args.get("nullable")
4733            if (
4734                other_type.expressions
4735                or (check_nullable and (self_is_nullable or other_is_nullable))
4736                or self.this == DataType.Type.USERDEFINED
4737                or other_type.this == DataType.Type.USERDEFINED
4738            ):
4739                matches = self == other_type
4740            else:
4741                matches = self.this == other_type.this
4742
4743            if matches:
4744                return True
4745        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>, <Type.LIST: 'LIST'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.ARRAY: 'ARRAY'>, <Type.UNION: 'UNION'>}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.FLOAT: 'FLOAT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}
NUMERIC_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.BIT: 'BIT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT128: 'UINT128'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT: 'UINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}
TEMPORAL_TYPES = {<Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME: 'DATETIME'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME2: 'DATETIME2'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}
@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:
4670    @classmethod
4671    def build(
4672        cls,
4673        dtype: DATA_TYPE,
4674        dialect: DialectType = None,
4675        udt: bool = False,
4676        copy: bool = True,
4677        **kwargs,
4678    ) -> DataType:
4679        """
4680        Constructs a DataType object.
4681
4682        Args:
4683            dtype: the data type of interest.
4684            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4685            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4686                DataType, thus creating a user-defined type.
4687            copy: whether to copy the data type.
4688            kwargs: additional arguments to pass in the constructor of DataType.
4689
4690        Returns:
4691            The constructed DataType object.
4692        """
4693        from sqlglot import parse_one
4694
4695        if isinstance(dtype, str):
4696            if dtype.upper() == "UNKNOWN":
4697                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4698
4699            try:
4700                data_type_exp = parse_one(
4701                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4702                )
4703            except ParseError:
4704                if udt:
4705                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4706                raise
4707        elif isinstance(dtype, DataType.Type):
4708            data_type_exp = DataType(this=dtype)
4709        elif isinstance(dtype, DataType):
4710            return maybe_copy(dtype, copy)
4711        else:
4712            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4713
4714        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:
4716    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4717        """
4718        Checks whether this DataType matches one of the provided data types. Nested types or precision
4719        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4720
4721        Args:
4722            dtypes: the data types to compare this DataType to.
4723            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4724                If false, it means that NULLABLE<INT> is equivalent to INT.
4725
4726        Returns:
4727            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4728        """
4729        self_is_nullable = self.args.get("nullable")
4730        for dtype in dtypes:
4731            other_type = DataType.build(dtype, copy=False, udt=True)
4732            other_is_nullable = other_type.args.get("nullable")
4733            if (
4734                other_type.expressions
4735                or (check_nullable and (self_is_nullable or other_is_nullable))
4736                or self.this == DataType.Type.USERDEFINED
4737                or other_type.this == DataType.Type.USERDEFINED
4738            ):
4739                matches = self == other_type
4740            else:
4741                matches = self.this == other_type.this
4742
4743            if matches:
4744                return True
4745        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):
4452    class Type(AutoName):
4453        ARRAY = auto()
4454        AGGREGATEFUNCTION = auto()
4455        SIMPLEAGGREGATEFUNCTION = auto()
4456        BIGDECIMAL = auto()
4457        BIGINT = auto()
4458        BIGSERIAL = auto()
4459        BINARY = auto()
4460        BIT = auto()
4461        BLOB = auto()
4462        BOOLEAN = auto()
4463        BPCHAR = auto()
4464        CHAR = auto()
4465        DATE = auto()
4466        DATE32 = auto()
4467        DATEMULTIRANGE = auto()
4468        DATERANGE = auto()
4469        DATETIME = auto()
4470        DATETIME2 = auto()
4471        DATETIME64 = auto()
4472        DECIMAL = auto()
4473        DECIMAL32 = auto()
4474        DECIMAL64 = auto()
4475        DECIMAL128 = auto()
4476        DECIMAL256 = auto()
4477        DOUBLE = auto()
4478        DYNAMIC = auto()
4479        ENUM = auto()
4480        ENUM8 = auto()
4481        ENUM16 = auto()
4482        FIXEDSTRING = auto()
4483        FLOAT = auto()
4484        GEOGRAPHY = auto()
4485        GEOMETRY = auto()
4486        POINT = auto()
4487        RING = auto()
4488        LINESTRING = auto()
4489        MULTILINESTRING = auto()
4490        POLYGON = auto()
4491        MULTIPOLYGON = auto()
4492        HLLSKETCH = auto()
4493        HSTORE = auto()
4494        IMAGE = auto()
4495        INET = auto()
4496        INT = auto()
4497        INT128 = auto()
4498        INT256 = auto()
4499        INT4MULTIRANGE = auto()
4500        INT4RANGE = auto()
4501        INT8MULTIRANGE = auto()
4502        INT8RANGE = auto()
4503        INTERVAL = auto()
4504        IPADDRESS = auto()
4505        IPPREFIX = auto()
4506        IPV4 = auto()
4507        IPV6 = auto()
4508        JSON = auto()
4509        JSONB = auto()
4510        LIST = auto()
4511        LONGBLOB = auto()
4512        LONGTEXT = auto()
4513        LOWCARDINALITY = auto()
4514        MAP = auto()
4515        MEDIUMBLOB = auto()
4516        MEDIUMINT = auto()
4517        MEDIUMTEXT = auto()
4518        MONEY = auto()
4519        NAME = auto()
4520        NCHAR = auto()
4521        NESTED = auto()
4522        NULL = auto()
4523        NUMMULTIRANGE = auto()
4524        NUMRANGE = auto()
4525        NVARCHAR = auto()
4526        OBJECT = auto()
4527        RANGE = auto()
4528        ROWVERSION = auto()
4529        SERIAL = auto()
4530        SET = auto()
4531        SMALLDATETIME = auto()
4532        SMALLINT = auto()
4533        SMALLMONEY = auto()
4534        SMALLSERIAL = auto()
4535        STRUCT = auto()
4536        SUPER = auto()
4537        TEXT = auto()
4538        TINYBLOB = auto()
4539        TINYTEXT = auto()
4540        TIME = auto()
4541        TIMETZ = auto()
4542        TIMESTAMP = auto()
4543        TIMESTAMPNTZ = auto()
4544        TIMESTAMPLTZ = auto()
4545        TIMESTAMPTZ = auto()
4546        TIMESTAMP_S = auto()
4547        TIMESTAMP_MS = auto()
4548        TIMESTAMP_NS = auto()
4549        TINYINT = auto()
4550        TSMULTIRANGE = auto()
4551        TSRANGE = auto()
4552        TSTZMULTIRANGE = auto()
4553        TSTZRANGE = auto()
4554        UBIGINT = auto()
4555        UINT = auto()
4556        UINT128 = auto()
4557        UINT256 = auto()
4558        UMEDIUMINT = auto()
4559        UDECIMAL = auto()
4560        UDOUBLE = auto()
4561        UNION = auto()
4562        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4563        USERDEFINED = "USER-DEFINED"
4564        USMALLINT = auto()
4565        UTINYINT = auto()
4566        UUID = auto()
4567        VARBINARY = auto()
4568        VARCHAR = auto()
4569        VARIANT = auto()
4570        VECTOR = auto()
4571        XML = auto()
4572        YEAR = auto()
4573        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'>
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):
4752class PseudoType(DataType):
4753    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4757class ObjectIdentifier(DataType):
4758    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4762class SubqueryPredicate(Predicate):
4763    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4766class All(SubqueryPredicate):
4767    pass
key = 'all'
class Any(SubqueryPredicate):
4770class Any(SubqueryPredicate):
4771    pass
key = 'any'
class Command(Expression):
4776class Command(Expression):
4777    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4780class Transaction(Expression):
4781    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4784class Commit(Expression):
4785    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4788class Rollback(Expression):
4789    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4792class Alter(Expression):
4793    arg_types = {
4794        "this": True,
4795        "kind": True,
4796        "actions": True,
4797        "exists": False,
4798        "only": False,
4799        "options": False,
4800        "cluster": False,
4801        "not_valid": False,
4802    }
4803
4804    @property
4805    def kind(self) -> t.Optional[str]:
4806        kind = self.args.get("kind")
4807        return kind and kind.upper()
4808
4809    @property
4810    def actions(self) -> t.List[Expression]:
4811        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]
4804    @property
4805    def kind(self) -> t.Optional[str]:
4806        kind = self.args.get("kind")
4807        return kind and kind.upper()
actions: List[Expression]
4809    @property
4810    def actions(self) -> t.List[Expression]:
4811        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4814class Analyze(Expression):
4815    arg_types = {
4816        "kind": False,
4817        "this": False,
4818        "options": False,
4819        "mode": False,
4820        "partition": False,
4821        "expression": False,
4822        "properties": False,
4823    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4826class AnalyzeStatistics(Expression):
4827    arg_types = {
4828        "kind": True,
4829        "option": False,
4830        "this": False,
4831        "expressions": False,
4832    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4835class AnalyzeHistogram(Expression):
4836    arg_types = {
4837        "this": True,
4838        "expressions": True,
4839        "expression": False,
4840        "update_options": False,
4841    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4844class AnalyzeSample(Expression):
4845    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4848class AnalyzeListChainedRows(Expression):
4849    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4852class AnalyzeDelete(Expression):
4853    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4856class AnalyzeWith(Expression):
4857    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4860class AnalyzeValidate(Expression):
4861    arg_types = {
4862        "kind": True,
4863        "this": False,
4864        "expression": False,
4865    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4868class AnalyzeColumns(Expression):
4869    pass
key = 'analyzecolumns'
class UsingData(Expression):
4872class UsingData(Expression):
4873    pass
key = 'usingdata'
class AddConstraint(Expression):
4876class AddConstraint(Expression):
4877    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4880class AttachOption(Expression):
4881    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4884class DropPartition(Expression):
4885    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4889class ReplacePartition(Expression):
4890    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4894class Binary(Condition):
4895    arg_types = {"this": True, "expression": True}
4896
4897    @property
4898    def left(self) -> Expression:
4899        return self.this
4900
4901    @property
4902    def right(self) -> Expression:
4903        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4897    @property
4898    def left(self) -> Expression:
4899        return self.this
right: Expression
4901    @property
4902    def right(self) -> Expression:
4903        return self.expression
key = 'binary'
class Add(Binary):
4906class Add(Binary):
4907    pass
key = 'add'
class Connector(Binary):
4910class Connector(Binary):
4911    pass
key = 'connector'
class BitwiseAnd(Binary):
4914class BitwiseAnd(Binary):
4915    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4918class BitwiseLeftShift(Binary):
4919    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4922class BitwiseOr(Binary):
4923    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4926class BitwiseRightShift(Binary):
4927    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4930class BitwiseXor(Binary):
4931    pass
key = 'bitwisexor'
class Div(Binary):
4934class Div(Binary):
4935    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):
4938class Overlaps(Binary):
4939    pass
key = 'overlaps'
class Dot(Binary):
4942class Dot(Binary):
4943    @property
4944    def is_star(self) -> bool:
4945        return self.expression.is_star
4946
4947    @property
4948    def name(self) -> str:
4949        return self.expression.name
4950
4951    @property
4952    def output_name(self) -> str:
4953        return self.name
4954
4955    @classmethod
4956    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4957        """Build a Dot object with a sequence of expressions."""
4958        if len(expressions) < 2:
4959            raise ValueError("Dot requires >= 2 expressions.")
4960
4961        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4962
4963    @property
4964    def parts(self) -> t.List[Expression]:
4965        """Return the parts of a table / column in order catalog, db, table."""
4966        this, *parts = self.flatten()
4967
4968        parts.reverse()
4969
4970        for arg in COLUMN_PARTS:
4971            part = this.args.get(arg)
4972
4973            if isinstance(part, Expression):
4974                parts.append(part)
4975
4976        parts.reverse()
4977        return parts
is_star: bool
4943    @property
4944    def is_star(self) -> bool:
4945        return self.expression.is_star

Checks whether an expression is a star.

name: str
4947    @property
4948    def name(self) -> str:
4949        return self.expression.name
output_name: str
4951    @property
4952    def output_name(self) -> str:
4953        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:
4955    @classmethod
4956    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4957        """Build a Dot object with a sequence of expressions."""
4958        if len(expressions) < 2:
4959            raise ValueError("Dot requires >= 2 expressions.")
4960
4961        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]
4963    @property
4964    def parts(self) -> t.List[Expression]:
4965        """Return the parts of a table / column in order catalog, db, table."""
4966        this, *parts = self.flatten()
4967
4968        parts.reverse()
4969
4970        for arg in COLUMN_PARTS:
4971            part = this.args.get(arg)
4972
4973            if isinstance(part, Expression):
4974                parts.append(part)
4975
4976        parts.reverse()
4977        return parts

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

key = 'dot'
class DPipe(Binary):
4980class DPipe(Binary):
4981    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4984class EQ(Binary, Predicate):
4985    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4988class NullSafeEQ(Binary, Predicate):
4989    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4992class NullSafeNEQ(Binary, Predicate):
4993    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4997class PropertyEQ(Binary):
4998    pass
key = 'propertyeq'
class Distance(Binary):
5001class Distance(Binary):
5002    pass
key = 'distance'
class Escape(Binary):
5005class Escape(Binary):
5006    pass
key = 'escape'
class Glob(Binary, Predicate):
5009class Glob(Binary, Predicate):
5010    pass
key = 'glob'
class GT(Binary, Predicate):
5013class GT(Binary, Predicate):
5014    pass
key = 'gt'
class GTE(Binary, Predicate):
5017class GTE(Binary, Predicate):
5018    pass
key = 'gte'
class ILike(Binary, Predicate):
5021class ILike(Binary, Predicate):
5022    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5025class ILikeAny(Binary, Predicate):
5026    pass
key = 'ilikeany'
class IntDiv(Binary):
5029class IntDiv(Binary):
5030    pass
key = 'intdiv'
class Is(Binary, Predicate):
5033class Is(Binary, Predicate):
5034    pass
key = 'is'
class Kwarg(Binary):
5037class Kwarg(Binary):
5038    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5041class Like(Binary, Predicate):
5042    pass
key = 'like'
class LikeAny(Binary, Predicate):
5045class LikeAny(Binary, Predicate):
5046    pass
key = 'likeany'
class LT(Binary, Predicate):
5049class LT(Binary, Predicate):
5050    pass
key = 'lt'
class LTE(Binary, Predicate):
5053class LTE(Binary, Predicate):
5054    pass
key = 'lte'
class Mod(Binary):
5057class Mod(Binary):
5058    pass
key = 'mod'
class Mul(Binary):
5061class Mul(Binary):
5062    pass
key = 'mul'
class NEQ(Binary, Predicate):
5065class NEQ(Binary, Predicate):
5066    pass
key = 'neq'
class Operator(Binary):
5070class Operator(Binary):
5071    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5074class SimilarTo(Binary, Predicate):
5075    pass
key = 'similarto'
class Slice(Binary):
5078class Slice(Binary):
5079    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5082class Sub(Binary):
5083    pass
key = 'sub'
class Unary(Condition):
5088class Unary(Condition):
5089    pass
key = 'unary'
class BitwiseNot(Unary):
5092class BitwiseNot(Unary):
5093    pass
key = 'bitwisenot'
class Not(Unary):
5096class Not(Unary):
5097    pass
key = 'not'
class Paren(Unary):
5100class Paren(Unary):
5101    @property
5102    def output_name(self) -> str:
5103        return self.this.name
output_name: str
5101    @property
5102    def output_name(self) -> str:
5103        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):
5106class Neg(Unary):
5107    def to_py(self) -> int | Decimal:
5108        if self.is_number:
5109            return self.this.to_py() * -1
5110        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5107    def to_py(self) -> int | Decimal:
5108        if self.is_number:
5109            return self.this.to_py() * -1
5110        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5113class Alias(Expression):
5114    arg_types = {"this": True, "alias": False}
5115
5116    @property
5117    def output_name(self) -> str:
5118        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5116    @property
5117    def output_name(self) -> str:
5118        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):
5123class PivotAlias(Alias):
5124    pass
key = 'pivotalias'
class PivotAny(Expression):
5129class PivotAny(Expression):
5130    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5133class Aliases(Expression):
5134    arg_types = {"this": True, "expressions": True}
5135
5136    @property
5137    def aliases(self):
5138        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5136    @property
5137    def aliases(self):
5138        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5142class AtIndex(Expression):
5143    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5146class AtTimeZone(Expression):
5147    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5150class FromTimeZone(Expression):
5151    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5154class Between(Predicate):
5155    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5158class Bracket(Condition):
5159    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5160    arg_types = {
5161        "this": True,
5162        "expressions": True,
5163        "offset": False,
5164        "safe": False,
5165        "returns_list_for_maps": False,
5166    }
5167
5168    @property
5169    def output_name(self) -> str:
5170        if len(self.expressions) == 1:
5171            return self.expressions[0].output_name
5172
5173        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5168    @property
5169    def output_name(self) -> str:
5170        if len(self.expressions) == 1:
5171            return self.expressions[0].output_name
5172
5173        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):
5176class Distinct(Expression):
5177    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5180class In(Predicate):
5181    arg_types = {
5182        "this": True,
5183        "expressions": False,
5184        "query": False,
5185        "unnest": False,
5186        "field": False,
5187        "is_global": False,
5188    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5192class ForIn(Expression):
5193    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5196class TimeUnit(Expression):
5197    """Automatically converts unit arg into a var."""
5198
5199    arg_types = {"unit": False}
5200
5201    UNABBREVIATED_UNIT_NAME = {
5202        "D": "DAY",
5203        "H": "HOUR",
5204        "M": "MINUTE",
5205        "MS": "MILLISECOND",
5206        "NS": "NANOSECOND",
5207        "Q": "QUARTER",
5208        "S": "SECOND",
5209        "US": "MICROSECOND",
5210        "W": "WEEK",
5211        "Y": "YEAR",
5212    }
5213
5214    VAR_LIKE = (Column, Literal, Var)
5215
5216    def __init__(self, **args):
5217        unit = args.get("unit")
5218        if isinstance(unit, self.VAR_LIKE):
5219            args["unit"] = Var(
5220                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5221            )
5222        elif isinstance(unit, Week):
5223            unit.set("this", Var(this=unit.this.name.upper()))
5224
5225        super().__init__(**args)
5226
5227    @property
5228    def unit(self) -> t.Optional[Var | IntervalSpan]:
5229        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5216    def __init__(self, **args):
5217        unit = args.get("unit")
5218        if isinstance(unit, self.VAR_LIKE):
5219            args["unit"] = Var(
5220                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5221            )
5222        elif isinstance(unit, Week):
5223            unit.set("this", Var(this=unit.this.name.upper()))
5224
5225        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]
5227    @property
5228    def unit(self) -> t.Optional[Var | IntervalSpan]:
5229        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5232class IntervalOp(TimeUnit):
5233    arg_types = {"unit": False, "expression": True}
5234
5235    def interval(self):
5236        return Interval(
5237            this=self.expression.copy(),
5238            unit=self.unit.copy() if self.unit else None,
5239        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5235    def interval(self):
5236        return Interval(
5237            this=self.expression.copy(),
5238            unit=self.unit.copy() if self.unit else None,
5239        )
key = 'intervalop'
class IntervalSpan(DataType):
5245class IntervalSpan(DataType):
5246    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5249class Interval(TimeUnit):
5250    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5253class IgnoreNulls(Expression):
5254    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5257class RespectNulls(Expression):
5258    pass
key = 'respectnulls'
class HavingMax(Expression):
5262class HavingMax(Expression):
5263    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5267class Func(Condition):
5268    """
5269    The base class for all function expressions.
5270
5271    Attributes:
5272        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5273            treated as a variable length argument and the argument's value will be stored as a list.
5274        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5275            function expression. These values are used to map this node to a name during parsing as
5276            well as to provide the function's name during SQL string generation. By default the SQL
5277            name is set to the expression's class name transformed to snake case.
5278    """
5279
5280    is_var_len_args = False
5281
5282    @classmethod
5283    def from_arg_list(cls, args):
5284        if cls.is_var_len_args:
5285            all_arg_keys = list(cls.arg_types)
5286            # If this function supports variable length argument treat the last argument as such.
5287            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5288            num_non_var = len(non_var_len_arg_keys)
5289
5290            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5291            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5292        else:
5293            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5294
5295        return cls(**args_dict)
5296
5297    @classmethod
5298    def sql_names(cls):
5299        if cls is Func:
5300            raise NotImplementedError(
5301                "SQL name is only supported by concrete function implementations"
5302            )
5303        if "_sql_names" not in cls.__dict__:
5304            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5305        return cls._sql_names
5306
5307    @classmethod
5308    def sql_name(cls):
5309        return cls.sql_names()[0]
5310
5311    @classmethod
5312    def default_parser_mappings(cls):
5313        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):
5282    @classmethod
5283    def from_arg_list(cls, args):
5284        if cls.is_var_len_args:
5285            all_arg_keys = list(cls.arg_types)
5286            # If this function supports variable length argument treat the last argument as such.
5287            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5288            num_non_var = len(non_var_len_arg_keys)
5289
5290            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5291            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5292        else:
5293            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5294
5295        return cls(**args_dict)
@classmethod
def sql_names(cls):
5297    @classmethod
5298    def sql_names(cls):
5299        if cls is Func:
5300            raise NotImplementedError(
5301                "SQL name is only supported by concrete function implementations"
5302            )
5303        if "_sql_names" not in cls.__dict__:
5304            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5305        return cls._sql_names
@classmethod
def sql_name(cls):
5307    @classmethod
5308    def sql_name(cls):
5309        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5311    @classmethod
5312    def default_parser_mappings(cls):
5313        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5316class AggFunc(Func):
5317    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5320class ParameterizedAgg(AggFunc):
5321    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5324class Abs(Func):
5325    pass
key = 'abs'
class ArgMax(AggFunc):
5328class ArgMax(AggFunc):
5329    arg_types = {"this": True, "expression": True, "count": False}
5330    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5333class ArgMin(AggFunc):
5334    arg_types = {"this": True, "expression": True, "count": False}
5335    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5338class ApproxTopK(AggFunc):
5339    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5342class Flatten(Func):
5343    pass
key = 'flatten'
class Transform(Func):
5347class Transform(Func):
5348    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5351class Anonymous(Func):
5352    arg_types = {"this": True, "expressions": False}
5353    is_var_len_args = True
5354
5355    @property
5356    def name(self) -> str:
5357        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
5355    @property
5356    def name(self) -> str:
5357        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5360class AnonymousAggFunc(AggFunc):
5361    arg_types = {"this": True, "expressions": False}
5362    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5366class CombinedAggFunc(AnonymousAggFunc):
5367    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5370class CombinedParameterizedAgg(ParameterizedAgg):
5371    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5376class Hll(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 = 'hll'
class ApproxDistinct(AggFunc):
5381class ApproxDistinct(AggFunc):
5382    arg_types = {"this": True, "accuracy": False}
5383    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5386class Apply(Func):
5387    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5390class Array(Func):
5391    arg_types = {"expressions": False, "bracket_notation": False}
5392    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5396class ToArray(Func):
5397    pass
key = 'toarray'
class List(Func):
5401class List(Func):
5402    arg_types = {"expressions": False}
5403    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5407class Pad(Func):
5408    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):
5413class ToChar(Func):
5414    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5419class ToNumber(Func):
5420    arg_types = {
5421        "this": True,
5422        "format": False,
5423        "nlsparam": False,
5424        "precision": False,
5425        "scale": False,
5426    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5430class ToDouble(Func):
5431    arg_types = {
5432        "this": True,
5433        "format": False,
5434    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5437class Columns(Func):
5438    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5442class Convert(Func):
5443    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5446class ConvertTimezone(Func):
5447    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):
5450class GenerateSeries(Func):
5451    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):
5457class ExplodingGenerateSeries(GenerateSeries):
5458    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5461class ArrayAgg(AggFunc):
5462    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5465class ArrayUniqueAgg(AggFunc):
5466    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5469class ArrayAll(Func):
5470    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5474class ArrayAny(Func):
5475    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5478class ArrayConcat(Func):
5479    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5480    arg_types = {"this": True, "expressions": False}
5481    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5484class ArrayConstructCompact(Func):
5485    arg_types = {"expressions": True}
5486    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5489class ArrayContains(Binary, Func):
5490    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5493class ArrayContainsAll(Binary, Func):
5494    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5497class ArrayFilter(Func):
5498    arg_types = {"this": True, "expression": True}
5499    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5502class ArrayToString(Func):
5503    arg_types = {"this": True, "expression": True, "null": False}
5504    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5508class String(Func):
5509    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5512class StringToArray(Func):
5513    arg_types = {"this": True, "expression": True, "null": False}
5514    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5517class ArrayOverlaps(Binary, Func):
5518    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5521class ArraySize(Func):
5522    arg_types = {"this": True, "expression": False}
5523    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5526class ArraySort(Func):
5527    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5530class ArraySum(Func):
5531    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5534class ArrayUnionAgg(AggFunc):
5535    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5538class Avg(AggFunc):
5539    pass
key = 'avg'
class AnyValue(AggFunc):
5542class AnyValue(AggFunc):
5543    pass
key = 'anyvalue'
class Lag(AggFunc):
5546class Lag(AggFunc):
5547    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5550class Lead(AggFunc):
5551    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5556class First(AggFunc):
5557    pass
key = 'first'
class Last(AggFunc):
5560class Last(AggFunc):
5561    pass
key = 'last'
class FirstValue(AggFunc):
5564class FirstValue(AggFunc):
5565    pass
key = 'firstvalue'
class LastValue(AggFunc):
5568class LastValue(AggFunc):
5569    pass
key = 'lastvalue'
class NthValue(AggFunc):
5572class NthValue(AggFunc):
5573    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5576class Case(Func):
5577    arg_types = {"this": False, "ifs": True, "default": False}
5578
5579    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5580        instance = maybe_copy(self, copy)
5581        instance.append(
5582            "ifs",
5583            If(
5584                this=maybe_parse(condition, copy=copy, **opts),
5585                true=maybe_parse(then, copy=copy, **opts),
5586            ),
5587        )
5588        return instance
5589
5590    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5591        instance = maybe_copy(self, copy)
5592        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5593        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:
5579    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5580        instance = maybe_copy(self, copy)
5581        instance.append(
5582            "ifs",
5583            If(
5584                this=maybe_parse(condition, copy=copy, **opts),
5585                true=maybe_parse(then, copy=copy, **opts),
5586            ),
5587        )
5588        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5590    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5591        instance = maybe_copy(self, copy)
5592        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5593        return instance
key = 'case'
class Cast(Func):
5596class Cast(Func):
5597    arg_types = {
5598        "this": True,
5599        "to": True,
5600        "format": False,
5601        "safe": False,
5602        "action": False,
5603        "default": False,
5604    }
5605
5606    @property
5607    def name(self) -> str:
5608        return self.this.name
5609
5610    @property
5611    def to(self) -> DataType:
5612        return self.args["to"]
5613
5614    @property
5615    def output_name(self) -> str:
5616        return self.name
5617
5618    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5619        """
5620        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5621        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5622        array<int> != array<float>.
5623
5624        Args:
5625            dtypes: the data types to compare this Cast's DataType to.
5626
5627        Returns:
5628            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5629        """
5630        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5606    @property
5607    def name(self) -> str:
5608        return self.this.name
to: DataType
5610    @property
5611    def to(self) -> DataType:
5612        return self.args["to"]
output_name: str
5614    @property
5615    def output_name(self) -> str:
5616        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:
5618    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5619        """
5620        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5621        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5622        array<int> != array<float>.
5623
5624        Args:
5625            dtypes: the data types to compare this Cast's DataType to.
5626
5627        Returns:
5628            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5629        """
5630        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):
5633class TryCast(Cast):
5634    pass
key = 'trycast'
class JSONCast(Cast):
5638class JSONCast(Cast):
5639    pass
key = 'jsoncast'
class Try(Func):
5642class Try(Func):
5643    pass
key = 'try'
class CastToStrType(Func):
5646class CastToStrType(Func):
5647    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5650class Collate(Binary, Func):
5651    pass
key = 'collate'
class Ceil(Func):
5654class Ceil(Func):
5655    arg_types = {"this": True, "decimals": False, "to": False}
5656    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5659class Coalesce(Func):
5660    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5661    is_var_len_args = True
5662    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5665class Chr(Func):
5666    arg_types = {"expressions": True, "charset": False}
5667    is_var_len_args = True
5668    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5671class Concat(Func):
5672    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5673    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5676class ConcatWs(Concat):
5677    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5680class Contains(Func):
5681    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5685class ConnectByRoot(Func):
5686    pass
key = 'connectbyroot'
class Count(AggFunc):
5689class Count(AggFunc):
5690    arg_types = {"this": False, "expressions": False, "big_int": False}
5691    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5694class CountIf(AggFunc):
5695    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5699class Cbrt(Func):
5700    pass
key = 'cbrt'
class CurrentDate(Func):
5703class CurrentDate(Func):
5704    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5707class CurrentDatetime(Func):
5708    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5711class CurrentTime(Func):
5712    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5715class CurrentTimestamp(Func):
5716    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5719class CurrentSchema(Func):
5720    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5723class CurrentUser(Func):
5724    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5727class DateAdd(Func, IntervalOp):
5728    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5731class DateBin(Func, IntervalOp):
5732    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):
5735class DateSub(Func, IntervalOp):
5736    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5739class DateDiff(Func, TimeUnit):
5740    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5741    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5744class DateTrunc(Func):
5745    arg_types = {"unit": True, "this": True, "zone": False}
5746
5747    def __init__(self, **args):
5748        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5749        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5750        unabbreviate = args.pop("unabbreviate", True)
5751
5752        unit = args.get("unit")
5753        if isinstance(unit, TimeUnit.VAR_LIKE):
5754            unit_name = unit.name.upper()
5755            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5756                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5757
5758            args["unit"] = Literal.string(unit_name)
5759        elif isinstance(unit, Week):
5760            unit.set("this", Literal.string(unit.this.name.upper()))
5761
5762        super().__init__(**args)
5763
5764    @property
5765    def unit(self) -> Expression:
5766        return self.args["unit"]
DateTrunc(**args)
5747    def __init__(self, **args):
5748        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5749        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5750        unabbreviate = args.pop("unabbreviate", True)
5751
5752        unit = args.get("unit")
5753        if isinstance(unit, TimeUnit.VAR_LIKE):
5754            unit_name = unit.name.upper()
5755            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5756                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5757
5758            args["unit"] = Literal.string(unit_name)
5759        elif isinstance(unit, Week):
5760            unit.set("this", Literal.string(unit.this.name.upper()))
5761
5762        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5764    @property
5765    def unit(self) -> Expression:
5766        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5771class Datetime(Func):
5772    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5775class DatetimeAdd(Func, IntervalOp):
5776    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5779class DatetimeSub(Func, IntervalOp):
5780    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5783class DatetimeDiff(Func, TimeUnit):
5784    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5787class DatetimeTrunc(Func, TimeUnit):
5788    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5791class DayOfWeek(Func):
5792    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5797class DayOfWeekIso(Func):
5798    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5801class DayOfMonth(Func):
5802    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5805class DayOfYear(Func):
5806    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5809class ToDays(Func):
5810    pass
key = 'todays'
class WeekOfYear(Func):
5813class WeekOfYear(Func):
5814    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5817class MonthsBetween(Func):
5818    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5821class MakeInterval(Func):
5822    arg_types = {
5823        "year": False,
5824        "month": False,
5825        "day": False,
5826        "hour": False,
5827        "minute": False,
5828        "second": False,
5829    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5832class LastDay(Func, TimeUnit):
5833    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5834    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5837class Extract(Func):
5838    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5841class Exists(Func, SubqueryPredicate):
5842    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5845class Timestamp(Func):
5846    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5849class TimestampAdd(Func, TimeUnit):
5850    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5853class TimestampSub(Func, TimeUnit):
5854    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5857class TimestampDiff(Func, TimeUnit):
5858    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5859    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5862class TimestampTrunc(Func, TimeUnit):
5863    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5866class TimeAdd(Func, TimeUnit):
5867    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5870class TimeSub(Func, TimeUnit):
5871    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5874class TimeDiff(Func, TimeUnit):
5875    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5878class TimeTrunc(Func, TimeUnit):
5879    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5882class DateFromParts(Func):
5883    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5884    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5887class TimeFromParts(Func):
5888    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5889    arg_types = {
5890        "hour": True,
5891        "min": True,
5892        "sec": True,
5893        "nano": False,
5894        "fractions": False,
5895        "precision": False,
5896    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5899class DateStrToDate(Func):
5900    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5903class DateToDateStr(Func):
5904    pass
key = 'datetodatestr'
class DateToDi(Func):
5907class DateToDi(Func):
5908    pass
key = 'datetodi'
class Date(Func):
5912class Date(Func):
5913    arg_types = {"this": False, "zone": False, "expressions": False}
5914    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5917class Day(Func):
5918    pass
key = 'day'
class Decode(Func):
5921class Decode(Func):
5922    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5925class DiToDate(Func):
5926    pass
key = 'ditodate'
class Encode(Func):
5929class Encode(Func):
5930    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5933class Exp(Func):
5934    pass
key = 'exp'
class Explode(Func, UDTF):
5938class Explode(Func, UDTF):
5939    arg_types = {"this": True, "expressions": False}
5940    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5944class Inline(Func):
5945    pass
key = 'inline'
class ExplodeOuter(Explode):
5948class ExplodeOuter(Explode):
5949    pass
key = 'explodeouter'
class Posexplode(Explode):
5952class Posexplode(Explode):
5953    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5956class PosexplodeOuter(Posexplode, ExplodeOuter):
5957    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5960class Unnest(Func, UDTF):
5961    arg_types = {
5962        "expressions": True,
5963        "alias": False,
5964        "offset": False,
5965        "explode_array": False,
5966    }
5967
5968    @property
5969    def selects(self) -> t.List[Expression]:
5970        columns = super().selects
5971        offset = self.args.get("offset")
5972        if offset:
5973            columns = columns + [to_identifier("offset") if offset is True else offset]
5974        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5968    @property
5969    def selects(self) -> t.List[Expression]:
5970        columns = super().selects
5971        offset = self.args.get("offset")
5972        if offset:
5973            columns = columns + [to_identifier("offset") if offset is True else offset]
5974        return columns
key = 'unnest'
class Floor(Func):
5977class Floor(Func):
5978    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5981class FromBase64(Func):
5982    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5985class FeaturesAtTime(Func):
5986    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):
5989class ToBase64(Func):
5990    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5994class FromISO8601Timestamp(Func):
5995    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5998class GapFill(Func):
5999    arg_types = {
6000        "this": True,
6001        "ts_column": True,
6002        "bucket_width": True,
6003        "partitioning_columns": False,
6004        "value_columns": False,
6005        "origin": False,
6006        "ignore_nulls": False,
6007    }
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):
6011class GenerateDateArray(Func):
6012    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6016class GenerateTimestampArray(Func):
6017    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6020class Greatest(Func):
6021    arg_types = {"this": True, "expressions": False}
6022    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6027class OverflowTruncateBehavior(Expression):
6028    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6031class GroupConcat(AggFunc):
6032    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6035class Hex(Func):
6036    pass
key = 'hex'
class LowerHex(Hex):
6039class LowerHex(Hex):
6040    pass
key = 'lowerhex'
class And(Connector, Func):
6043class And(Connector, Func):
6044    pass
key = 'and'
class Or(Connector, Func):
6047class Or(Connector, Func):
6048    pass
key = 'or'
class Xor(Connector, Func):
6051class Xor(Connector, Func):
6052    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6055class If(Func):
6056    arg_types = {"this": True, "true": True, "false": False}
6057    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6060class Nullif(Func):
6061    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6064class Initcap(Func):
6065    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6068class IsAscii(Func):
6069    pass
key = 'isascii'
class IsNan(Func):
6072class IsNan(Func):
6073    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6077class Int64(Func):
6078    pass
key = 'int64'
class IsInf(Func):
6081class IsInf(Func):
6082    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6086class JSON(Expression):
6087    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6090class JSONPath(Expression):
6091    arg_types = {"expressions": True, "escape": False}
6092
6093    @property
6094    def output_name(self) -> str:
6095        last_segment = self.expressions[-1].this
6096        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6093    @property
6094    def output_name(self) -> str:
6095        last_segment = self.expressions[-1].this
6096        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):
6099class JSONPathPart(Expression):
6100    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6103class JSONPathFilter(JSONPathPart):
6104    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6107class JSONPathKey(JSONPathPart):
6108    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6111class JSONPathRecursive(JSONPathPart):
6112    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6115class JSONPathRoot(JSONPathPart):
6116    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6119class JSONPathScript(JSONPathPart):
6120    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6123class JSONPathSlice(JSONPathPart):
6124    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6127class JSONPathSelector(JSONPathPart):
6128    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6131class JSONPathSubscript(JSONPathPart):
6132    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6135class JSONPathUnion(JSONPathPart):
6136    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6139class JSONPathWildcard(JSONPathPart):
6140    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6143class FormatJson(Expression):
6144    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6147class JSONKeyValue(Expression):
6148    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6151class JSONObject(Func):
6152    arg_types = {
6153        "expressions": False,
6154        "null_handling": False,
6155        "unique_keys": False,
6156        "return_type": False,
6157        "encoding": False,
6158    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6161class JSONObjectAgg(AggFunc):
6162    arg_types = {
6163        "expressions": False,
6164        "null_handling": False,
6165        "unique_keys": False,
6166        "return_type": False,
6167        "encoding": False,
6168    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6172class JSONBObjectAgg(AggFunc):
6173    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6177class JSONArray(Func):
6178    arg_types = {
6179        "expressions": True,
6180        "null_handling": False,
6181        "return_type": False,
6182        "strict": False,
6183    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6187class JSONArrayAgg(Func):
6188    arg_types = {
6189        "this": True,
6190        "order": False,
6191        "null_handling": False,
6192        "return_type": False,
6193        "strict": False,
6194    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6197class JSONExists(Func):
6198    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):
6203class JSONColumnDef(Expression):
6204    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):
6207class JSONSchema(Expression):
6208    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6212class JSONValue(Expression):
6213    arg_types = {
6214        "this": True,
6215        "path": True,
6216        "returning": False,
6217        "on_condition": False,
6218    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6221class JSONValueArray(Func):
6222    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6226class JSONTable(Func):
6227    arg_types = {
6228        "this": True,
6229        "schema": True,
6230        "path": False,
6231        "error_handling": False,
6232        "empty_handling": False,
6233    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6237class ObjectInsert(Func):
6238    arg_types = {
6239        "this": True,
6240        "key": True,
6241        "value": True,
6242        "update_flag": False,
6243    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6246class OpenJSONColumnDef(Expression):
6247    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):
6250class OpenJSON(Func):
6251    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6254class JSONBContains(Binary, Func):
6255    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6258class JSONBExists(Func):
6259    arg_types = {"this": True, "path": True}
6260    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6263class JSONExtract(Binary, Func):
6264    arg_types = {
6265        "this": True,
6266        "expression": True,
6267        "only_json_types": False,
6268        "expressions": False,
6269        "variant_extract": False,
6270        "json_query": False,
6271        "option": False,
6272        "quote": False,
6273        "on_condition": False,
6274    }
6275    _sql_names = ["JSON_EXTRACT"]
6276    is_var_len_args = True
6277
6278    @property
6279    def output_name(self) -> str:
6280        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
6278    @property
6279    def output_name(self) -> str:
6280        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):
6284class JSONExtractQuote(Expression):
6285    arg_types = {
6286        "option": True,
6287        "scalar": False,
6288    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6291class JSONExtractArray(Func):
6292    arg_types = {"this": True, "expression": False}
6293    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6296class JSONExtractScalar(Binary, Func):
6297    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6298    _sql_names = ["JSON_EXTRACT_SCALAR"]
6299    is_var_len_args = True
6300
6301    @property
6302    def output_name(self) -> str:
6303        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
6301    @property
6302    def output_name(self) -> str:
6303        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):
6306class JSONBExtract(Binary, Func):
6307    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6310class JSONBExtractScalar(Binary, Func):
6311    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6314class JSONFormat(Func):
6315    arg_types = {"this": False, "options": False, "is_json": False}
6316    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6320class JSONArrayContains(Binary, Predicate, Func):
6321    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6324class ParseJSON(Func):
6325    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6326    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6327    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6328    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6331class Least(Func):
6332    arg_types = {"this": True, "expressions": False}
6333    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6336class Left(Func):
6337    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6344class Length(Func):
6345    arg_types = {"this": True, "binary": False, "encoding": False}
6346    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6349class Levenshtein(Func):
6350    arg_types = {
6351        "this": True,
6352        "expression": False,
6353        "ins_cost": False,
6354        "del_cost": False,
6355        "sub_cost": False,
6356        "max_dist": False,
6357    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6360class Ln(Func):
6361    pass
key = 'ln'
class Log(Func):
6364class Log(Func):
6365    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6368class LogicalOr(AggFunc):
6369    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6372class LogicalAnd(AggFunc):
6373    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6376class Lower(Func):
6377    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6380class Map(Func):
6381    arg_types = {"keys": False, "values": False}
6382
6383    @property
6384    def keys(self) -> t.List[Expression]:
6385        keys = self.args.get("keys")
6386        return keys.expressions if keys else []
6387
6388    @property
6389    def values(self) -> t.List[Expression]:
6390        values = self.args.get("values")
6391        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6383    @property
6384    def keys(self) -> t.List[Expression]:
6385        keys = self.args.get("keys")
6386        return keys.expressions if keys else []
values: List[Expression]
6388    @property
6389    def values(self) -> t.List[Expression]:
6390        values = self.args.get("values")
6391        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6395class ToMap(Func):
6396    pass
key = 'tomap'
class MapFromEntries(Func):
6399class MapFromEntries(Func):
6400    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6404class ScopeResolution(Expression):
6405    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6408class Stream(Expression):
6409    pass
key = 'stream'
class StarMap(Func):
6412class StarMap(Func):
6413    pass
key = 'starmap'
class VarMap(Func):
6416class VarMap(Func):
6417    arg_types = {"keys": True, "values": True}
6418    is_var_len_args = True
6419
6420    @property
6421    def keys(self) -> t.List[Expression]:
6422        return self.args["keys"].expressions
6423
6424    @property
6425    def values(self) -> t.List[Expression]:
6426        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6420    @property
6421    def keys(self) -> t.List[Expression]:
6422        return self.args["keys"].expressions
values: List[Expression]
6424    @property
6425    def values(self) -> t.List[Expression]:
6426        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6430class MatchAgainst(Func):
6431    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6434class Max(AggFunc):
6435    arg_types = {"this": True, "expressions": False}
6436    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6439class MD5(Func):
6440    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6444class MD5Digest(Func):
6445    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6448class Median(AggFunc):
6449    pass
key = 'median'
class Min(AggFunc):
6452class Min(AggFunc):
6453    arg_types = {"this": True, "expressions": False}
6454    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6457class Month(Func):
6458    pass
key = 'month'
class AddMonths(Func):
6461class AddMonths(Func):
6462    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6465class Nvl2(Func):
6466    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6469class Normalize(Func):
6470    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6473class Overlay(Func):
6474    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):
6478class Predict(Func):
6479    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6482class Pow(Binary, Func):
6483    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6486class PercentileCont(AggFunc):
6487    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6490class PercentileDisc(AggFunc):
6491    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6494class Quantile(AggFunc):
6495    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6498class ApproxQuantile(Quantile):
6499    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):
6502class Quarter(Func):
6503    pass
key = 'quarter'
class Rand(Func):
6508class Rand(Func):
6509    _sql_names = ["RAND", "RANDOM"]
6510    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6513class Randn(Func):
6514    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6517class RangeN(Func):
6518    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6521class ReadCSV(Func):
6522    _sql_names = ["READ_CSV"]
6523    is_var_len_args = True
6524    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6527class Reduce(Func):
6528    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):
6531class RegexpExtract(Func):
6532    arg_types = {
6533        "this": True,
6534        "expression": True,
6535        "position": False,
6536        "occurrence": False,
6537        "parameters": False,
6538        "group": False,
6539    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6542class RegexpExtractAll(Func):
6543    arg_types = {
6544        "this": True,
6545        "expression": True,
6546        "position": False,
6547        "occurrence": False,
6548        "parameters": False,
6549        "group": False,
6550    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6553class RegexpReplace(Func):
6554    arg_types = {
6555        "this": True,
6556        "expression": True,
6557        "replacement": False,
6558        "position": False,
6559        "occurrence": False,
6560        "modifiers": False,
6561    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6564class RegexpLike(Binary, Func):
6565    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6568class RegexpILike(Binary, Func):
6569    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6574class RegexpSplit(Func):
6575    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6578class Repeat(Func):
6579    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6584class Round(Func):
6585    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6588class RowNumber(Func):
6589    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6592class SafeDivide(Func):
6593    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6596class SHA(Func):
6597    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6600class SHA2(Func):
6601    _sql_names = ["SHA2"]
6602    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6605class Sign(Func):
6606    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6609class SortArray(Func):
6610    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6613class Split(Func):
6614    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6618class SplitPart(Func):
6619    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6624class Substring(Func):
6625    _sql_names = ["SUBSTRING", "SUBSTR"]
6626    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6629class StandardHash(Func):
6630    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6633class StartsWith(Func):
6634    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6635    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6638class StrPosition(Func):
6639    arg_types = {
6640        "this": True,
6641        "substr": True,
6642        "position": False,
6643        "occurrence": False,
6644    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6647class StrToDate(Func):
6648    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6651class StrToTime(Func):
6652    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):
6657class StrToUnix(Func):
6658    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6663class StrToMap(Func):
6664    arg_types = {
6665        "this": True,
6666        "pair_delim": False,
6667        "key_value_delim": False,
6668        "duplicate_resolution_callback": False,
6669    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6672class NumberToStr(Func):
6673    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6676class FromBase(Func):
6677    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6680class Struct(Func):
6681    arg_types = {"expressions": False}
6682    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6685class StructExtract(Func):
6686    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6691class Stuff(Func):
6692    _sql_names = ["STUFF", "INSERT"]
6693    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):
6696class Sum(AggFunc):
6697    pass
key = 'sum'
class Sqrt(Func):
6700class Sqrt(Func):
6701    pass
key = 'sqrt'
class Stddev(AggFunc):
6704class Stddev(AggFunc):
6705    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6708class StddevPop(AggFunc):
6709    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6712class StddevSamp(AggFunc):
6713    pass
key = 'stddevsamp'
class Time(Func):
6717class Time(Func):
6718    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6721class TimeToStr(Func):
6722    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):
6725class TimeToTimeStr(Func):
6726    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6729class TimeToUnix(Func):
6730    pass
key = 'timetounix'
class TimeStrToDate(Func):
6733class TimeStrToDate(Func):
6734    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6737class TimeStrToTime(Func):
6738    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6741class TimeStrToUnix(Func):
6742    pass
key = 'timestrtounix'
class Trim(Func):
6745class Trim(Func):
6746    arg_types = {
6747        "this": True,
6748        "expression": False,
6749        "position": False,
6750        "collation": False,
6751    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6754class TsOrDsAdd(Func, TimeUnit):
6755    # return_type is used to correctly cast the arguments of this expression when transpiling it
6756    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6757
6758    @property
6759    def return_type(self) -> DataType:
6760        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
6758    @property
6759    def return_type(self) -> DataType:
6760        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6763class TsOrDsDiff(Func, TimeUnit):
6764    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6767class TsOrDsToDateStr(Func):
6768    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6771class TsOrDsToDate(Func):
6772    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6775class TsOrDsToDatetime(Func):
6776    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6779class TsOrDsToTime(Func):
6780    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6783class TsOrDsToTimestamp(Func):
6784    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6787class TsOrDiToDi(Func):
6788    pass
key = 'tsorditodi'
class Unhex(Func):
6791class Unhex(Func):
6792    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6795class Unicode(Func):
6796    pass
key = 'unicode'
class UnixDate(Func):
6800class UnixDate(Func):
6801    pass
key = 'unixdate'
class UnixToStr(Func):
6804class UnixToStr(Func):
6805    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6810class UnixToTime(Func):
6811    arg_types = {
6812        "this": True,
6813        "scale": False,
6814        "zone": False,
6815        "hours": False,
6816        "minutes": False,
6817        "format": False,
6818    }
6819
6820    SECONDS = Literal.number(0)
6821    DECIS = Literal.number(1)
6822    CENTIS = Literal.number(2)
6823    MILLIS = Literal.number(3)
6824    DECIMILLIS = Literal.number(4)
6825    CENTIMILLIS = Literal.number(5)
6826    MICROS = Literal.number(6)
6827    DECIMICROS = Literal.number(7)
6828    CENTIMICROS = Literal.number(8)
6829    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):
6832class UnixToTimeStr(Func):
6833    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6836class UnixSeconds(Func):
6837    pass
key = 'unixseconds'
class Uuid(Func):
6840class Uuid(Func):
6841    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6842
6843    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6846class TimestampFromParts(Func):
6847    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6848    arg_types = {
6849        "year": True,
6850        "month": True,
6851        "day": True,
6852        "hour": True,
6853        "min": True,
6854        "sec": True,
6855        "nano": False,
6856        "zone": False,
6857        "milli": False,
6858    }
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):
6861class Upper(Func):
6862    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6865class Corr(Binary, AggFunc):
6866    pass
key = 'corr'
class Variance(AggFunc):
6869class Variance(AggFunc):
6870    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6873class VariancePop(AggFunc):
6874    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6877class CovarSamp(Binary, AggFunc):
6878    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6881class CovarPop(Binary, AggFunc):
6882    pass
key = 'covarpop'
class Week(Func):
6885class Week(Func):
6886    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6889class XMLElement(Func):
6890    _sql_names = ["XMLELEMENT"]
6891    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6894class XMLTable(Func):
6895    arg_types = {
6896        "this": True,
6897        "namespaces": False,
6898        "passing": False,
6899        "columns": False,
6900        "by_ref": False,
6901    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6904class XMLNamespace(Expression):
6905    pass
key = 'xmlnamespace'
class Year(Func):
6908class Year(Func):
6909    pass
key = 'year'
class Use(Expression):
6912class Use(Expression):
6913    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6916class Merge(DML):
6917    arg_types = {
6918        "this": True,
6919        "using": True,
6920        "on": True,
6921        "whens": True,
6922        "with": False,
6923        "returning": False,
6924    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6927class When(Expression):
6928    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):
6931class Whens(Expression):
6932    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6933
6934    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6939class NextValueFor(Func):
6940    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6945class Semicolon(Expression):
6946    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:
6986def maybe_parse(
6987    sql_or_expression: ExpOrStr,
6988    *,
6989    into: t.Optional[IntoType] = None,
6990    dialect: DialectType = None,
6991    prefix: t.Optional[str] = None,
6992    copy: bool = False,
6993    **opts,
6994) -> Expression:
6995    """Gracefully handle a possible string or expression.
6996
6997    Example:
6998        >>> maybe_parse("1")
6999        Literal(this=1, is_string=False)
7000        >>> maybe_parse(to_identifier("x"))
7001        Identifier(this=x, quoted=False)
7002
7003    Args:
7004        sql_or_expression: the SQL code string or an expression
7005        into: the SQLGlot Expression to parse into
7006        dialect: the dialect used to parse the input expressions (in the case that an
7007            input expression is a SQL string).
7008        prefix: a string to prefix the sql with before it gets parsed
7009            (automatically includes a space)
7010        copy: whether to copy the expression.
7011        **opts: other options to use to parse the input expressions (again, in the case
7012            that an input expression is a SQL string).
7013
7014    Returns:
7015        Expression: the parsed or given expression.
7016    """
7017    if isinstance(sql_or_expression, Expression):
7018        if copy:
7019            return sql_or_expression.copy()
7020        return sql_or_expression
7021
7022    if sql_or_expression is None:
7023        raise ParseError("SQL cannot be None")
7024
7025    import sqlglot
7026
7027    sql = str(sql_or_expression)
7028    if prefix:
7029        sql = f"{prefix} {sql}"
7030
7031    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):
7042def maybe_copy(instance, copy=True):
7043    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:
7298def union(
7299    *expressions: ExpOrStr,
7300    distinct: bool = True,
7301    dialect: DialectType = None,
7302    copy: bool = True,
7303    **opts,
7304) -> Union:
7305    """
7306    Initializes a syntax tree for the `UNION` operation.
7307
7308    Example:
7309        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7310        'SELECT * FROM foo UNION SELECT * FROM bla'
7311
7312    Args:
7313        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7314            If `Expression` instances are passed, they will be used as-is.
7315        distinct: set the DISTINCT flag if and only if this is true.
7316        dialect: the dialect used to parse the input expression.
7317        copy: whether to copy the expression.
7318        opts: other options to use to parse the input expressions.
7319
7320    Returns:
7321        The new Union instance.
7322    """
7323    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7324    return _apply_set_operation(
7325        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7326    )

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:
7329def intersect(
7330    *expressions: ExpOrStr,
7331    distinct: bool = True,
7332    dialect: DialectType = None,
7333    copy: bool = True,
7334    **opts,
7335) -> Intersect:
7336    """
7337    Initializes a syntax tree for the `INTERSECT` operation.
7338
7339    Example:
7340        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7341        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7342
7343    Args:
7344        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7345            If `Expression` instances are passed, they will be used as-is.
7346        distinct: set the DISTINCT flag if and only if this is true.
7347        dialect: the dialect used to parse the input expression.
7348        copy: whether to copy the expression.
7349        opts: other options to use to parse the input expressions.
7350
7351    Returns:
7352        The new Intersect instance.
7353    """
7354    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7355    return _apply_set_operation(
7356        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7357    )

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:
7360def except_(
7361    *expressions: ExpOrStr,
7362    distinct: bool = True,
7363    dialect: DialectType = None,
7364    copy: bool = True,
7365    **opts,
7366) -> Except:
7367    """
7368    Initializes a syntax tree for the `EXCEPT` operation.
7369
7370    Example:
7371        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7372        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7373
7374    Args:
7375        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7376            If `Expression` instances are passed, they will be used as-is.
7377        distinct: set the DISTINCT flag if and only if this is true.
7378        dialect: the dialect used to parse the input expression.
7379        copy: whether to copy the expression.
7380        opts: other options to use to parse the input expressions.
7381
7382    Returns:
7383        The new Except instance.
7384    """
7385    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7386    return _apply_set_operation(
7387        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7388    )

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:
7391def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7392    """
7393    Initializes a syntax tree from one or multiple SELECT expressions.
7394
7395    Example:
7396        >>> select("col1", "col2").from_("tbl").sql()
7397        'SELECT col1, col2 FROM tbl'
7398
7399    Args:
7400        *expressions: the SQL code string to parse as the expressions of a
7401            SELECT statement. If an Expression instance is passed, this is used as-is.
7402        dialect: the dialect used to parse the input expressions (in the case that an
7403            input expression is a SQL string).
7404        **opts: other options to use to parse the input expressions (again, in the case
7405            that an input expression is a SQL string).
7406
7407    Returns:
7408        Select: the syntax tree for the SELECT statement.
7409    """
7410    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:
7413def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7414    """
7415    Initializes a syntax tree from a FROM expression.
7416
7417    Example:
7418        >>> from_("tbl").select("col1", "col2").sql()
7419        'SELECT col1, col2 FROM tbl'
7420
7421    Args:
7422        *expression: the SQL code string to parse as the FROM expressions of a
7423            SELECT statement. If an Expression instance is passed, this is used as-is.
7424        dialect: the dialect used to parse the input expression (in the case that the
7425            input expression is a SQL string).
7426        **opts: other options to use to parse the input expressions (again, in the case
7427            that the input expression is a SQL string).
7428
7429    Returns:
7430        Select: the syntax tree for the SELECT statement.
7431    """
7432    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:
7435def update(
7436    table: str | Table,
7437    properties: t.Optional[dict] = None,
7438    where: t.Optional[ExpOrStr] = None,
7439    from_: t.Optional[ExpOrStr] = None,
7440    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7441    dialect: DialectType = None,
7442    **opts,
7443) -> Update:
7444    """
7445    Creates an update statement.
7446
7447    Example:
7448        >>> 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()
7449        "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"
7450
7451    Args:
7452        properties: dictionary of properties to SET which are
7453            auto converted to sql objects eg None -> NULL
7454        where: sql conditional parsed into a WHERE statement
7455        from_: sql statement parsed into a FROM statement
7456        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7457        dialect: the dialect used to parse the input expressions.
7458        **opts: other options to use to parse the input expressions.
7459
7460    Returns:
7461        Update: the syntax tree for the UPDATE statement.
7462    """
7463    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7464    if properties:
7465        update_expr.set(
7466            "expressions",
7467            [
7468                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7469                for k, v in properties.items()
7470            ],
7471        )
7472    if from_:
7473        update_expr.set(
7474            "from",
7475            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7476        )
7477    if isinstance(where, Condition):
7478        where = Where(this=where)
7479    if where:
7480        update_expr.set(
7481            "where",
7482            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7483        )
7484    if with_:
7485        cte_list = [
7486            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7487            for alias, qry in with_.items()
7488        ]
7489        update_expr.set(
7490            "with",
7491            With(expressions=cte_list),
7492        )
7493    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:
7496def delete(
7497    table: ExpOrStr,
7498    where: t.Optional[ExpOrStr] = None,
7499    returning: t.Optional[ExpOrStr] = None,
7500    dialect: DialectType = None,
7501    **opts,
7502) -> Delete:
7503    """
7504    Builds a delete statement.
7505
7506    Example:
7507        >>> delete("my_table", where="id > 1").sql()
7508        'DELETE FROM my_table WHERE id > 1'
7509
7510    Args:
7511        where: sql conditional parsed into a WHERE statement
7512        returning: sql conditional parsed into a RETURNING statement
7513        dialect: the dialect used to parse the input expressions.
7514        **opts: other options to use to parse the input expressions.
7515
7516    Returns:
7517        Delete: the syntax tree for the DELETE statement.
7518    """
7519    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7520    if where:
7521        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7522    if returning:
7523        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7524    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:
7527def insert(
7528    expression: ExpOrStr,
7529    into: ExpOrStr,
7530    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7531    overwrite: t.Optional[bool] = None,
7532    returning: t.Optional[ExpOrStr] = None,
7533    dialect: DialectType = None,
7534    copy: bool = True,
7535    **opts,
7536) -> Insert:
7537    """
7538    Builds an INSERT statement.
7539
7540    Example:
7541        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7542        'INSERT INTO tbl VALUES (1, 2, 3)'
7543
7544    Args:
7545        expression: the sql string or expression of the INSERT statement
7546        into: the tbl to insert data to.
7547        columns: optionally the table's column names.
7548        overwrite: whether to INSERT OVERWRITE or not.
7549        returning: sql conditional parsed into a RETURNING statement
7550        dialect: the dialect used to parse the input expressions.
7551        copy: whether to copy the expression.
7552        **opts: other options to use to parse the input expressions.
7553
7554    Returns:
7555        Insert: the syntax tree for the INSERT statement.
7556    """
7557    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7558    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7559
7560    if columns:
7561        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7562
7563    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7564
7565    if returning:
7566        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7567
7568    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:
7571def merge(
7572    *when_exprs: ExpOrStr,
7573    into: ExpOrStr,
7574    using: ExpOrStr,
7575    on: ExpOrStr,
7576    returning: t.Optional[ExpOrStr] = None,
7577    dialect: DialectType = None,
7578    copy: bool = True,
7579    **opts,
7580) -> Merge:
7581    """
7582    Builds a MERGE statement.
7583
7584    Example:
7585        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7586        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7587        ...       into="my_table",
7588        ...       using="source_table",
7589        ...       on="my_table.id = source_table.id").sql()
7590        '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)'
7591
7592    Args:
7593        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7594        into: The target table to merge data into.
7595        using: The source table to merge data from.
7596        on: The join condition for the merge.
7597        returning: The columns to return from the merge.
7598        dialect: The dialect used to parse the input expressions.
7599        copy: Whether to copy the expression.
7600        **opts: Other options to use to parse the input expressions.
7601
7602    Returns:
7603        Merge: The syntax tree for the MERGE statement.
7604    """
7605    expressions: t.List[Expression] = []
7606    for when_expr in when_exprs:
7607        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7608        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7609
7610    merge = Merge(
7611        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7612        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7613        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7614        whens=Whens(expressions=expressions),
7615    )
7616    if returning:
7617        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7618
7619    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:
7622def condition(
7623    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7624) -> Condition:
7625    """
7626    Initialize a logical condition expression.
7627
7628    Example:
7629        >>> condition("x=1").sql()
7630        'x = 1'
7631
7632        This is helpful for composing larger logical syntax trees:
7633        >>> where = condition("x=1")
7634        >>> where = where.and_("y=1")
7635        >>> Select().from_("tbl").select("*").where(where).sql()
7636        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7637
7638    Args:
7639        *expression: the SQL code string to parse.
7640            If an Expression instance is passed, this is used as-is.
7641        dialect: the dialect used to parse the input expression (in the case that the
7642            input expression is a SQL string).
7643        copy: Whether to copy `expression` (only applies to expressions).
7644        **opts: other options to use to parse the input expressions (again, in the case
7645            that the input expression is a SQL string).
7646
7647    Returns:
7648        The new Condition instance
7649    """
7650    return maybe_parse(
7651        expression,
7652        into=Condition,
7653        dialect=dialect,
7654        copy=copy,
7655        **opts,
7656    )

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:
7659def and_(
7660    *expressions: t.Optional[ExpOrStr],
7661    dialect: DialectType = None,
7662    copy: bool = True,
7663    wrap: bool = True,
7664    **opts,
7665) -> Condition:
7666    """
7667    Combine multiple conditions with an AND logical operator.
7668
7669    Example:
7670        >>> and_("x=1", and_("y=1", "z=1")).sql()
7671        'x = 1 AND (y = 1 AND z = 1)'
7672
7673    Args:
7674        *expressions: the SQL code strings to parse.
7675            If an Expression instance is passed, this is used as-is.
7676        dialect: the dialect used to parse the input expression.
7677        copy: whether to copy `expressions` (only applies to Expressions).
7678        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7679            precedence issues, but can be turned off when the produced AST is too deep and
7680            causes recursion-related issues.
7681        **opts: other options to use to parse the input expressions.
7682
7683    Returns:
7684        The new condition
7685    """
7686    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:
7689def or_(
7690    *expressions: t.Optional[ExpOrStr],
7691    dialect: DialectType = None,
7692    copy: bool = True,
7693    wrap: bool = True,
7694    **opts,
7695) -> Condition:
7696    """
7697    Combine multiple conditions with an OR logical operator.
7698
7699    Example:
7700        >>> or_("x=1", or_("y=1", "z=1")).sql()
7701        'x = 1 OR (y = 1 OR z = 1)'
7702
7703    Args:
7704        *expressions: the SQL code strings to parse.
7705            If an Expression instance is passed, this is used as-is.
7706        dialect: the dialect used to parse the input expression.
7707        copy: whether to copy `expressions` (only applies to Expressions).
7708        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7709            precedence issues, but can be turned off when the produced AST is too deep and
7710            causes recursion-related issues.
7711        **opts: other options to use to parse the input expressions.
7712
7713    Returns:
7714        The new condition
7715    """
7716    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:
7719def xor(
7720    *expressions: t.Optional[ExpOrStr],
7721    dialect: DialectType = None,
7722    copy: bool = True,
7723    wrap: bool = True,
7724    **opts,
7725) -> Condition:
7726    """
7727    Combine multiple conditions with an XOR logical operator.
7728
7729    Example:
7730        >>> xor("x=1", xor("y=1", "z=1")).sql()
7731        'x = 1 XOR (y = 1 XOR z = 1)'
7732
7733    Args:
7734        *expressions: the SQL code strings to parse.
7735            If an Expression instance is passed, this is used as-is.
7736        dialect: the dialect used to parse the input expression.
7737        copy: whether to copy `expressions` (only applies to Expressions).
7738        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7739            precedence issues, but can be turned off when the produced AST is too deep and
7740            causes recursion-related issues.
7741        **opts: other options to use to parse the input expressions.
7742
7743    Returns:
7744        The new condition
7745    """
7746    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:
7749def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7750    """
7751    Wrap a condition with a NOT operator.
7752
7753    Example:
7754        >>> not_("this_suit='black'").sql()
7755        "NOT this_suit = 'black'"
7756
7757    Args:
7758        expression: the SQL code string to parse.
7759            If an Expression instance is passed, this is used as-is.
7760        dialect: the dialect used to parse the input expression.
7761        copy: whether to copy the expression or not.
7762        **opts: other options to use to parse the input expressions.
7763
7764    Returns:
7765        The new condition.
7766    """
7767    this = condition(
7768        expression,
7769        dialect=dialect,
7770        copy=copy,
7771        **opts,
7772    )
7773    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:
7776def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7777    """
7778    Wrap an expression in parentheses.
7779
7780    Example:
7781        >>> paren("5 + 3").sql()
7782        '(5 + 3)'
7783
7784    Args:
7785        expression: the SQL code string to parse.
7786            If an Expression instance is passed, this is used as-is.
7787        copy: whether to copy the expression or not.
7788
7789    Returns:
7790        The wrapped expression.
7791    """
7792    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):
7808def to_identifier(name, quoted=None, copy=True):
7809    """Builds an identifier.
7810
7811    Args:
7812        name: The name to turn into an identifier.
7813        quoted: Whether to force quote the identifier.
7814        copy: Whether to copy name if it's an Identifier.
7815
7816    Returns:
7817        The identifier ast node.
7818    """
7819
7820    if name is None:
7821        return None
7822
7823    if isinstance(name, Identifier):
7824        identifier = maybe_copy(name, copy)
7825    elif isinstance(name, str):
7826        identifier = Identifier(
7827            this=name,
7828            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7829        )
7830    else:
7831        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7832    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:
7835def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7836    """
7837    Parses a given string into an identifier.
7838
7839    Args:
7840        name: The name to parse into an identifier.
7841        dialect: The dialect to parse against.
7842
7843    Returns:
7844        The identifier ast node.
7845    """
7846    try:
7847        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7848    except (ParseError, TokenError):
7849        expression = to_identifier(name)
7850
7851    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:
7857def to_interval(interval: str | Literal) -> Interval:
7858    """Builds an interval expression from a string like '1 day' or '5 months'."""
7859    if isinstance(interval, Literal):
7860        if not interval.is_string:
7861            raise ValueError("Invalid interval string.")
7862
7863        interval = interval.this
7864
7865    interval = maybe_parse(f"INTERVAL {interval}")
7866    assert isinstance(interval, Interval)
7867    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:
7870def to_table(
7871    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7872) -> Table:
7873    """
7874    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7875    If a table is passed in then that table is returned.
7876
7877    Args:
7878        sql_path: a `[catalog].[schema].[table]` string.
7879        dialect: the source dialect according to which the table name will be parsed.
7880        copy: Whether to copy a table if it is passed in.
7881        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7882
7883    Returns:
7884        A table expression.
7885    """
7886    if isinstance(sql_path, Table):
7887        return maybe_copy(sql_path, copy=copy)
7888
7889    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7890
7891    for k, v in kwargs.items():
7892        table.set(k, v)
7893
7894    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:
7897def to_column(
7898    sql_path: str | Column,
7899    quoted: t.Optional[bool] = None,
7900    dialect: DialectType = None,
7901    copy: bool = True,
7902    **kwargs,
7903) -> Column:
7904    """
7905    Create a column from a `[table].[column]` sql path. Table is optional.
7906    If a column is passed in then that column is returned.
7907
7908    Args:
7909        sql_path: a `[table].[column]` string.
7910        quoted: Whether or not to force quote identifiers.
7911        dialect: the source dialect according to which the column name will be parsed.
7912        copy: Whether to copy a column if it is passed in.
7913        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7914
7915    Returns:
7916        A column expression.
7917    """
7918    if isinstance(sql_path, Column):
7919        return maybe_copy(sql_path, copy=copy)
7920
7921    try:
7922        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7923    except ParseError:
7924        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7925
7926    for k, v in kwargs.items():
7927        col.set(k, v)
7928
7929    if quoted:
7930        for i in col.find_all(Identifier):
7931            i.set("quoted", True)
7932
7933    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):
7936def alias_(
7937    expression: ExpOrStr,
7938    alias: t.Optional[str | Identifier],
7939    table: bool | t.Sequence[str | Identifier] = False,
7940    quoted: t.Optional[bool] = None,
7941    dialect: DialectType = None,
7942    copy: bool = True,
7943    **opts,
7944):
7945    """Create an Alias expression.
7946
7947    Example:
7948        >>> alias_('foo', 'bar').sql()
7949        'foo AS bar'
7950
7951        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7952        '(SELECT 1, 2) AS bar(a, b)'
7953
7954    Args:
7955        expression: the SQL code strings to parse.
7956            If an Expression instance is passed, this is used as-is.
7957        alias: the alias name to use. If the name has
7958            special characters it is quoted.
7959        table: Whether to create a table alias, can also be a list of columns.
7960        quoted: whether to quote the alias
7961        dialect: the dialect used to parse the input expression.
7962        copy: Whether to copy the expression.
7963        **opts: other options to use to parse the input expressions.
7964
7965    Returns:
7966        Alias: the aliased expression
7967    """
7968    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7969    alias = to_identifier(alias, quoted=quoted)
7970
7971    if table:
7972        table_alias = TableAlias(this=alias)
7973        exp.set("alias", table_alias)
7974
7975        if not isinstance(table, bool):
7976            for column in table:
7977                table_alias.append("columns", to_identifier(column, quoted=quoted))
7978
7979        return exp
7980
7981    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7982    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7983    # for the complete Window expression.
7984    #
7985    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7986
7987    if "alias" in exp.arg_types and not isinstance(exp, Window):
7988        exp.set("alias", alias)
7989        return exp
7990    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:
7993def subquery(
7994    expression: ExpOrStr,
7995    alias: t.Optional[Identifier | str] = None,
7996    dialect: DialectType = None,
7997    **opts,
7998) -> Select:
7999    """
8000    Build a subquery expression that's selected from.
8001
8002    Example:
8003        >>> subquery('select x from tbl', 'bar').select('x').sql()
8004        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8005
8006    Args:
8007        expression: the SQL code strings to parse.
8008            If an Expression instance is passed, this is used as-is.
8009        alias: the alias name to use.
8010        dialect: the dialect used to parse the input expression.
8011        **opts: other options to use to parse the input expressions.
8012
8013    Returns:
8014        A new Select instance with the subquery expression included.
8015    """
8016
8017    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8018    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):
8049def column(
8050    col,
8051    table=None,
8052    db=None,
8053    catalog=None,
8054    *,
8055    fields=None,
8056    quoted=None,
8057    copy=True,
8058):
8059    """
8060    Build a Column.
8061
8062    Args:
8063        col: Column name.
8064        table: Table name.
8065        db: Database name.
8066        catalog: Catalog name.
8067        fields: Additional fields using dots.
8068        quoted: Whether to force quotes on the column's identifiers.
8069        copy: Whether to copy identifiers if passed in.
8070
8071    Returns:
8072        The new Column instance.
8073    """
8074    this = Column(
8075        this=to_identifier(col, quoted=quoted, copy=copy),
8076        table=to_identifier(table, quoted=quoted, copy=copy),
8077        db=to_identifier(db, quoted=quoted, copy=copy),
8078        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8079    )
8080
8081    if fields:
8082        this = Dot.build(
8083            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8084        )
8085    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:
8088def cast(
8089    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8090) -> Cast:
8091    """Cast an expression to a data type.
8092
8093    Example:
8094        >>> cast('x + 1', 'int').sql()
8095        'CAST(x + 1 AS INT)'
8096
8097    Args:
8098        expression: The expression to cast.
8099        to: The datatype to cast to.
8100        copy: Whether to copy the supplied expressions.
8101        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8102            - The expression to be cast is already a exp.Cast expression
8103            - The existing cast is to a type that is logically equivalent to new type
8104
8105            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8106            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8107            and instead just return the original expression `CAST(x as DATETIME)`.
8108
8109            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8110            mapping is applied in the target dialect generator.
8111
8112    Returns:
8113        The new Cast instance.
8114    """
8115    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8116    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8117
8118    # dont re-cast if the expression is already a cast to the correct type
8119    if isinstance(expr, Cast):
8120        from sqlglot.dialects.dialect import Dialect
8121
8122        target_dialect = Dialect.get_or_raise(dialect)
8123        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8124
8125        existing_cast_type: DataType.Type = expr.to.this
8126        new_cast_type: DataType.Type = data_type.this
8127        types_are_equivalent = type_mapping.get(
8128            existing_cast_type, existing_cast_type.value
8129        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8130
8131        if expr.is_type(data_type) or types_are_equivalent:
8132            return expr
8133
8134    expr = Cast(this=expr, to=data_type)
8135    expr.type = data_type
8136
8137    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:
8140def table_(
8141    table: Identifier | str,
8142    db: t.Optional[Identifier | str] = None,
8143    catalog: t.Optional[Identifier | str] = None,
8144    quoted: t.Optional[bool] = None,
8145    alias: t.Optional[Identifier | str] = None,
8146) -> Table:
8147    """Build a Table.
8148
8149    Args:
8150        table: Table name.
8151        db: Database name.
8152        catalog: Catalog name.
8153        quote: Whether to force quotes on the table's identifiers.
8154        alias: Table's alias.
8155
8156    Returns:
8157        The new Table instance.
8158    """
8159    return Table(
8160        this=to_identifier(table, quoted=quoted) if table else None,
8161        db=to_identifier(db, quoted=quoted) if db else None,
8162        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8163        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8164    )

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:
8167def values(
8168    values: t.Iterable[t.Tuple[t.Any, ...]],
8169    alias: t.Optional[str] = None,
8170    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8171) -> Values:
8172    """Build VALUES statement.
8173
8174    Example:
8175        >>> values([(1, '2')]).sql()
8176        "VALUES (1, '2')"
8177
8178    Args:
8179        values: values statements that will be converted to SQL
8180        alias: optional alias
8181        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8182         If either are provided then an alias is also required.
8183
8184    Returns:
8185        Values: the Values expression object
8186    """
8187    if columns and not alias:
8188        raise ValueError("Alias is required when providing columns")
8189
8190    return Values(
8191        expressions=[convert(tup) for tup in values],
8192        alias=(
8193            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8194            if columns
8195            else (TableAlias(this=to_identifier(alias)) if alias else None)
8196        ),
8197    )

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:
8200def var(name: t.Optional[ExpOrStr]) -> Var:
8201    """Build a SQL variable.
8202
8203    Example:
8204        >>> repr(var('x'))
8205        'Var(this=x)'
8206
8207        >>> repr(var(column('x', table='y')))
8208        'Var(this=x)'
8209
8210    Args:
8211        name: The name of the var or an expression who's name will become the var.
8212
8213    Returns:
8214        The new variable node.
8215    """
8216    if not name:
8217        raise ValueError("Cannot convert empty name into var.")
8218
8219    if isinstance(name, Expression):
8220        name = name.name
8221    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:
8224def rename_table(
8225    old_name: str | Table,
8226    new_name: str | Table,
8227    dialect: DialectType = None,
8228) -> Alter:
8229    """Build ALTER TABLE... RENAME... expression
8230
8231    Args:
8232        old_name: The old name of the table
8233        new_name: The new name of the table
8234        dialect: The dialect to parse the table.
8235
8236    Returns:
8237        Alter table expression
8238    """
8239    old_table = to_table(old_name, dialect=dialect)
8240    new_table = to_table(new_name, dialect=dialect)
8241    return Alter(
8242        this=old_table,
8243        kind="TABLE",
8244        actions=[
8245            AlterRename(this=new_table),
8246        ],
8247    )

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:
8250def rename_column(
8251    table_name: str | Table,
8252    old_column_name: str | Column,
8253    new_column_name: str | Column,
8254    exists: t.Optional[bool] = None,
8255    dialect: DialectType = None,
8256) -> Alter:
8257    """Build ALTER TABLE... RENAME COLUMN... expression
8258
8259    Args:
8260        table_name: Name of the table
8261        old_column: The old name of the column
8262        new_column: The new name of the column
8263        exists: Whether to add the `IF EXISTS` clause
8264        dialect: The dialect to parse the table/column.
8265
8266    Returns:
8267        Alter table expression
8268    """
8269    table = to_table(table_name, dialect=dialect)
8270    old_column = to_column(old_column_name, dialect=dialect)
8271    new_column = to_column(new_column_name, dialect=dialect)
8272    return Alter(
8273        this=table,
8274        kind="TABLE",
8275        actions=[
8276            RenameColumn(this=old_column, to=new_column, exists=exists),
8277        ],
8278    )

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:
8281def convert(value: t.Any, copy: bool = False) -> Expression:
8282    """Convert a python value into an expression object.
8283
8284    Raises an error if a conversion is not possible.
8285
8286    Args:
8287        value: A python object.
8288        copy: Whether to copy `value` (only applies to Expressions and collections).
8289
8290    Returns:
8291        The equivalent expression object.
8292    """
8293    if isinstance(value, Expression):
8294        return maybe_copy(value, copy)
8295    if isinstance(value, str):
8296        return Literal.string(value)
8297    if isinstance(value, bool):
8298        return Boolean(this=value)
8299    if value is None or (isinstance(value, float) and math.isnan(value)):
8300        return null()
8301    if isinstance(value, numbers.Number):
8302        return Literal.number(value)
8303    if isinstance(value, bytes):
8304        return HexString(this=value.hex())
8305    if isinstance(value, datetime.datetime):
8306        datetime_literal = Literal.string(value.isoformat(sep=" "))
8307
8308        tz = None
8309        if value.tzinfo:
8310            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8311            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8312            tz = Literal.string(str(value.tzinfo))
8313
8314        return TimeStrToTime(this=datetime_literal, zone=tz)
8315    if isinstance(value, datetime.date):
8316        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8317        return DateStrToDate(this=date_literal)
8318    if isinstance(value, tuple):
8319        if hasattr(value, "_fields"):
8320            return Struct(
8321                expressions=[
8322                    PropertyEQ(
8323                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8324                    )
8325                    for k in value._fields
8326                ]
8327            )
8328        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8329    if isinstance(value, list):
8330        return Array(expressions=[convert(v, copy=copy) for v in value])
8331    if isinstance(value, dict):
8332        return Map(
8333            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8334            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8335        )
8336    if hasattr(value, "__dict__"):
8337        return Struct(
8338            expressions=[
8339                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8340                for k, v in value.__dict__.items()
8341            ]
8342        )
8343    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:
8346def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8347    """
8348    Replace children of an expression with the result of a lambda fun(child) -> exp.
8349    """
8350    for k, v in tuple(expression.args.items()):
8351        is_list_arg = type(v) is list
8352
8353        child_nodes = v if is_list_arg else [v]
8354        new_child_nodes = []
8355
8356        for cn in child_nodes:
8357            if isinstance(cn, Expression):
8358                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8359                    new_child_nodes.append(child_node)
8360            else:
8361                new_child_nodes.append(cn)
8362
8363        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:
8366def replace_tree(
8367    expression: Expression,
8368    fun: t.Callable,
8369    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8370) -> Expression:
8371    """
8372    Replace an entire tree with the result of function calls on each node.
8373
8374    This will be traversed in reverse dfs, so leaves first.
8375    If new nodes are created as a result of function calls, they will also be traversed.
8376    """
8377    stack = list(expression.dfs(prune=prune))
8378
8379    while stack:
8380        node = stack.pop()
8381        new_node = fun(node)
8382
8383        if new_node is not node:
8384            node.replace(new_node)
8385
8386            if isinstance(new_node, Expression):
8387                stack.append(new_node)
8388
8389    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]:
8392def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8393    """
8394    Return all table names referenced through columns in an expression.
8395
8396    Example:
8397        >>> import sqlglot
8398        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8399        ['a', 'c']
8400
8401    Args:
8402        expression: expression to find table names.
8403        exclude: a table name to exclude
8404
8405    Returns:
8406        A list of unique names.
8407    """
8408    return {
8409        table
8410        for table in (column.table for column in expression.find_all(Column))
8411        if table and table != exclude
8412    }

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:
8415def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8416    """Get the full name of a table as a string.
8417
8418    Args:
8419        table: Table expression node or string.
8420        dialect: The dialect to generate the table name for.
8421        identify: Determines when an identifier should be quoted. Possible values are:
8422            False (default): Never quote, except in cases where it's mandatory by the dialect.
8423            True: Always quote.
8424
8425    Examples:
8426        >>> from sqlglot import exp, parse_one
8427        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8428        'a.b.c'
8429
8430    Returns:
8431        The table name.
8432    """
8433
8434    table = maybe_parse(table, into=Table, dialect=dialect)
8435
8436    if not table:
8437        raise ValueError(f"Cannot parse {table}")
8438
8439    return ".".join(
8440        (
8441            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8442            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8443            else part.name
8444        )
8445        for part in table.parts
8446    )

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:
8449def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8450    """Returns a case normalized table name without quotes.
8451
8452    Args:
8453        table: the table to normalize
8454        dialect: the dialect to use for normalization rules
8455        copy: whether to copy the expression.
8456
8457    Examples:
8458        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8459        'A-B.c'
8460    """
8461    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8462
8463    return ".".join(
8464        p.name
8465        for p in normalize_identifiers(
8466            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8467        ).parts
8468    )

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:
8471def replace_tables(
8472    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8473) -> E:
8474    """Replace all tables in expression according to the mapping.
8475
8476    Args:
8477        expression: expression node to be transformed and replaced.
8478        mapping: mapping of table names.
8479        dialect: the dialect of the mapping table
8480        copy: whether to copy the expression.
8481
8482    Examples:
8483        >>> from sqlglot import exp, parse_one
8484        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8485        'SELECT * FROM c /* a.b */'
8486
8487    Returns:
8488        The mapped expression.
8489    """
8490
8491    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8492
8493    def _replace_tables(node: Expression) -> Expression:
8494        if isinstance(node, Table) and node.meta.get("replace") is not False:
8495            original = normalize_table_name(node, dialect=dialect)
8496            new_name = mapping.get(original)
8497
8498            if new_name:
8499                table = to_table(
8500                    new_name,
8501                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8502                    dialect=dialect,
8503                )
8504                table.add_comments([original])
8505                return table
8506        return node
8507
8508    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:
8511def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8512    """Replace placeholders in an expression.
8513
8514    Args:
8515        expression: expression node to be transformed and replaced.
8516        args: positional names that will substitute unnamed placeholders in the given order.
8517        kwargs: keyword arguments that will substitute named placeholders.
8518
8519    Examples:
8520        >>> from sqlglot import exp, parse_one
8521        >>> replace_placeholders(
8522        ...     parse_one("select * from :tbl where ? = ?"),
8523        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8524        ... ).sql()
8525        "SELECT * FROM foo WHERE str_col = 'b'"
8526
8527    Returns:
8528        The mapped expression.
8529    """
8530
8531    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8532        if isinstance(node, Placeholder):
8533            if node.this:
8534                new_name = kwargs.get(node.this)
8535                if new_name is not None:
8536                    return convert(new_name)
8537            else:
8538                try:
8539                    return convert(next(args))
8540                except StopIteration:
8541                    pass
8542        return node
8543
8544    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:
8547def expand(
8548    expression: Expression,
8549    sources: t.Dict[str, Query | t.Callable[[], Query]],
8550    dialect: DialectType = None,
8551    copy: bool = True,
8552) -> Expression:
8553    """Transforms an expression by expanding all referenced sources into subqueries.
8554
8555    Examples:
8556        >>> from sqlglot import parse_one
8557        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8558        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8559
8560        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8561        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8562
8563    Args:
8564        expression: The expression to expand.
8565        sources: A dict of name to query or a callable that provides a query on demand.
8566        dialect: The dialect of the sources dict or the callable.
8567        copy: Whether to copy the expression during transformation. Defaults to True.
8568
8569    Returns:
8570        The transformed expression.
8571    """
8572    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8573
8574    def _expand(node: Expression):
8575        if isinstance(node, Table):
8576            name = normalize_table_name(node, dialect=dialect)
8577            source = normalized_sources.get(name)
8578
8579            if source:
8580                # Create a subquery with the same alias (or table name if no alias)
8581                parsed_source = source() if callable(source) else source
8582                subquery = parsed_source.subquery(node.alias or name)
8583                subquery.comments = [f"source: {name}"]
8584
8585                # Continue expanding within the subquery
8586                return subquery.transform(_expand, copy=False)
8587
8588        return node
8589
8590    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:
8593def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8594    """
8595    Returns a Func expression.
8596
8597    Examples:
8598        >>> func("abs", 5).sql()
8599        'ABS(5)'
8600
8601        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8602        'CAST(5 AS DOUBLE)'
8603
8604    Args:
8605        name: the name of the function to build.
8606        args: the args used to instantiate the function of interest.
8607        copy: whether to copy the argument expressions.
8608        dialect: the source dialect.
8609        kwargs: the kwargs used to instantiate the function of interest.
8610
8611    Note:
8612        The arguments `args` and `kwargs` are mutually exclusive.
8613
8614    Returns:
8615        An instance of the function of interest, or an anonymous function, if `name` doesn't
8616        correspond to an existing `sqlglot.expressions.Func` class.
8617    """
8618    if args and kwargs:
8619        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8620
8621    from sqlglot.dialects.dialect import Dialect
8622
8623    dialect = Dialect.get_or_raise(dialect)
8624
8625    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8626    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8627
8628    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8629    if constructor:
8630        if converted:
8631            if "dialect" in constructor.__code__.co_varnames:
8632                function = constructor(converted, dialect=dialect)
8633            else:
8634                function = constructor(converted)
8635        elif constructor.__name__ == "from_arg_list":
8636            function = constructor.__self__(**kwargs)  # type: ignore
8637        else:
8638            constructor = FUNCTION_BY_NAME.get(name.upper())
8639            if constructor:
8640                function = constructor(**kwargs)
8641            else:
8642                raise ValueError(
8643                    f"Unable to convert '{name}' into a Func. Either manually construct "
8644                    "the Func expression of interest or parse the function call."
8645                )
8646    else:
8647        kwargs = kwargs or {"expressions": converted}
8648        function = Anonymous(this=name, **kwargs)
8649
8650    for error_message in function.error_messages(converted):
8651        raise ValueError(error_message)
8652
8653    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:
8656def case(
8657    expression: t.Optional[ExpOrStr] = None,
8658    **opts,
8659) -> Case:
8660    """
8661    Initialize a CASE statement.
8662
8663    Example:
8664        case().when("a = 1", "foo").else_("bar")
8665
8666    Args:
8667        expression: Optionally, the input expression (not all dialects support this)
8668        **opts: Extra keyword arguments for parsing `expression`
8669    """
8670    if expression is not None:
8671        this = maybe_parse(expression, **opts)
8672    else:
8673        this = None
8674    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:
8677def array(
8678    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8679) -> Array:
8680    """
8681    Returns an array.
8682
8683    Examples:
8684        >>> array(1, 'x').sql()
8685        'ARRAY(1, x)'
8686
8687    Args:
8688        expressions: the expressions to add to the array.
8689        copy: whether to copy the argument expressions.
8690        dialect: the source dialect.
8691        kwargs: the kwargs used to instantiate the function of interest.
8692
8693    Returns:
8694        An array expression.
8695    """
8696    return Array(
8697        expressions=[
8698            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8699            for expression in expressions
8700        ]
8701    )

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:
8704def tuple_(
8705    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8706) -> Tuple:
8707    """
8708    Returns an tuple.
8709
8710    Examples:
8711        >>> tuple_(1, 'x').sql()
8712        '(1, x)'
8713
8714    Args:
8715        expressions: the expressions to add to the tuple.
8716        copy: whether to copy the argument expressions.
8717        dialect: the source dialect.
8718        kwargs: the kwargs used to instantiate the function of interest.
8719
8720    Returns:
8721        A tuple expression.
8722    """
8723    return Tuple(
8724        expressions=[
8725            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8726            for expression in expressions
8727        ]
8728    )

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:
8731def true() -> Boolean:
8732    """
8733    Returns a true Boolean expression.
8734    """
8735    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8738def false() -> Boolean:
8739    """
8740    Returns a false Boolean expression.
8741    """
8742    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8745def null() -> Null:
8746    """
8747    Returns a Null expression.
8748    """
8749    return Null()

Returns a Null expression.

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