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

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

def to_column(self, copy: bool = True) -> Expression:
3341    def to_column(self, copy: bool = True) -> Expression:
3342        parts = self.parts
3343        last_part = parts[-1]
3344
3345        if isinstance(last_part, Identifier):
3346            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3347        else:
3348            # This branch will be reached if a function or array is wrapped in a `Table`
3349            col = last_part
3350
3351        alias = self.args.get("alias")
3352        if alias:
3353            col = alias_(col, alias.this, copy=copy)
3354
3355        return col
key = 'table'
class SetOperation(Query):
3358class SetOperation(Query):
3359    arg_types = {
3360        "with": False,
3361        "this": True,
3362        "expression": True,
3363        "distinct": False,
3364        "by_name": False,
3365        **QUERY_MODIFIERS,
3366    }
3367
3368    def select(
3369        self: S,
3370        *expressions: t.Optional[ExpOrStr],
3371        append: bool = True,
3372        dialect: DialectType = None,
3373        copy: bool = True,
3374        **opts,
3375    ) -> S:
3376        this = maybe_copy(self, copy)
3377        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3378        this.expression.unnest().select(
3379            *expressions, append=append, dialect=dialect, copy=False, **opts
3380        )
3381        return this
3382
3383    @property
3384    def named_selects(self) -> t.List[str]:
3385        return self.this.unnest().named_selects
3386
3387    @property
3388    def is_star(self) -> bool:
3389        return self.this.is_star or self.expression.is_star
3390
3391    @property
3392    def selects(self) -> t.List[Expression]:
3393        return self.this.unnest().selects
3394
3395    @property
3396    def left(self) -> Query:
3397        return self.this
3398
3399    @property
3400    def right(self) -> Query:
3401        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, '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:
3368    def select(
3369        self: S,
3370        *expressions: t.Optional[ExpOrStr],
3371        append: bool = True,
3372        dialect: DialectType = None,
3373        copy: bool = True,
3374        **opts,
3375    ) -> S:
3376        this = maybe_copy(self, copy)
3377        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3378        this.expression.unnest().select(
3379            *expressions, append=append, dialect=dialect, copy=False, **opts
3380        )
3381        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]
3383    @property
3384    def named_selects(self) -> t.List[str]:
3385        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3387    @property
3388    def is_star(self) -> bool:
3389        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3391    @property
3392    def selects(self) -> t.List[Expression]:
3393        return self.this.unnest().selects

Returns the query's projections.

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

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:
3460    def set_(
3461        self,
3462        *expressions: ExpOrStr,
3463        append: bool = True,
3464        dialect: DialectType = None,
3465        copy: bool = True,
3466        **opts,
3467    ) -> Update:
3468        """
3469        Append to or set the SET expressions.
3470
3471        Example:
3472            >>> Update().table("my_table").set_("x = 1").sql()
3473            'UPDATE my_table SET x = 1'
3474
3475        Args:
3476            *expressions: the SQL code strings to parse.
3477                If `Expression` instance(s) are passed, they will be used as-is.
3478                Multiple expressions are combined with a comma.
3479            append: if `True`, add the new expressions to any existing SET expressions.
3480                Otherwise, this resets the expressions.
3481            dialect: the dialect used to parse the input expressions.
3482            copy: if `False`, modify this expression instance in-place.
3483            opts: other options to use to parse the input expressions.
3484        """
3485        return _apply_list_builder(
3486            *expressions,
3487            instance=self,
3488            arg="expressions",
3489            append=append,
3490            into=Expression,
3491            prefix=None,
3492            dialect=dialect,
3493            copy=copy,
3494            **opts,
3495        )

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:
3497    def where(
3498        self,
3499        *expressions: t.Optional[ExpOrStr],
3500        append: bool = True,
3501        dialect: DialectType = None,
3502        copy: bool = True,
3503        **opts,
3504    ) -> Select:
3505        """
3506        Append to or set the WHERE expressions.
3507
3508        Example:
3509            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3510            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3511
3512        Args:
3513            *expressions: the SQL code strings to parse.
3514                If an `Expression` instance is passed, it will be used as-is.
3515                Multiple expressions are combined with an AND operator.
3516            append: if `True`, AND the new expressions to any existing expression.
3517                Otherwise, this resets the expression.
3518            dialect: the dialect used to parse the input expressions.
3519            copy: if `False`, modify this expression instance in-place.
3520            opts: other options to use to parse the input expressions.
3521
3522        Returns:
3523            Select: the modified expression.
3524        """
3525        return _apply_conjunction_builder(
3526            *expressions,
3527            instance=self,
3528            arg="where",
3529            append=append,
3530            into=Where,
3531            dialect=dialect,
3532            copy=copy,
3533            **opts,
3534        )

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:
3536    def from_(
3537        self,
3538        expression: t.Optional[ExpOrStr] = None,
3539        dialect: DialectType = None,
3540        copy: bool = True,
3541        **opts,
3542    ) -> Update:
3543        """
3544        Set the FROM expression.
3545
3546        Example:
3547            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3548            'UPDATE my_table SET x = 1 FROM baz'
3549
3550        Args:
3551            expression : the SQL code strings to parse.
3552                If a `From` instance is passed, this is used as-is.
3553                If another `Expression` instance is passed, it will be wrapped in a `From`.
3554                If nothing is passed in then a from is not applied to the expression
3555            dialect: the dialect used to parse the input expression.
3556            copy: if `False`, modify this expression instance in-place.
3557            opts: other options to use to parse the input expressions.
3558
3559        Returns:
3560            The modified Update expression.
3561        """
3562        if not expression:
3563            return maybe_copy(self, copy)
3564
3565        return _apply_builder(
3566            expression=expression,
3567            instance=self,
3568            arg="from",
3569            into=From,
3570            prefix="FROM",
3571            dialect=dialect,
3572            copy=copy,
3573            **opts,
3574        )

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:
3576    def with_(
3577        self,
3578        alias: ExpOrStr,
3579        as_: ExpOrStr,
3580        recursive: t.Optional[bool] = None,
3581        materialized: t.Optional[bool] = None,
3582        append: bool = True,
3583        dialect: DialectType = None,
3584        copy: bool = True,
3585        **opts,
3586    ) -> Update:
3587        """
3588        Append to or set the common table expressions.
3589
3590        Example:
3591            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3592            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3593
3594        Args:
3595            alias: the SQL code string to parse as the table name.
3596                If an `Expression` instance is passed, this is used as-is.
3597            as_: the SQL code string to parse as the table expression.
3598                If an `Expression` instance is passed, it will be used as-is.
3599            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3600            materialized: set the MATERIALIZED part of the expression.
3601            append: if `True`, add to any existing expressions.
3602                Otherwise, this resets the expressions.
3603            dialect: the dialect used to parse the input expression.
3604            copy: if `False`, modify this expression instance in-place.
3605            opts: other options to use to parse the input expressions.
3606
3607        Returns:
3608            The modified expression.
3609        """
3610        return _apply_cte_builder(
3611            self,
3612            alias,
3613            as_,
3614            recursive=recursive,
3615            materialized=materialized,
3616            append=append,
3617            dialect=dialect,
3618            copy=copy,
3619            **opts,
3620        )

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

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:
3700    def group_by(
3701        self,
3702        *expressions: t.Optional[ExpOrStr],
3703        append: bool = True,
3704        dialect: DialectType = None,
3705        copy: bool = True,
3706        **opts,
3707    ) -> Select:
3708        """
3709        Set the GROUP BY expression.
3710
3711        Example:
3712            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3713            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3714
3715        Args:
3716            *expressions: the SQL code strings to parse.
3717                If a `Group` instance is passed, this is used as-is.
3718                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3719                If nothing is passed in then a group by is not applied to the expression
3720            append: if `True`, add to any existing expressions.
3721                Otherwise, this flattens all the `Group` expression into a single expression.
3722            dialect: the dialect used to parse the input expression.
3723            copy: if `False`, modify this expression instance in-place.
3724            opts: other options to use to parse the input expressions.
3725
3726        Returns:
3727            The modified Select expression.
3728        """
3729        if not expressions:
3730            return self if not copy else self.copy()
3731
3732        return _apply_child_list_builder(
3733            *expressions,
3734            instance=self,
3735            arg="group",
3736            append=append,
3737            copy=copy,
3738            prefix="GROUP BY",
3739            into=Group,
3740            dialect=dialect,
3741            **opts,
3742        )

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

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

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:
3824    def select(
3825        self,
3826        *expressions: t.Optional[ExpOrStr],
3827        append: bool = True,
3828        dialect: DialectType = None,
3829        copy: bool = True,
3830        **opts,
3831    ) -> Select:
3832        return _apply_list_builder(
3833            *expressions,
3834            instance=self,
3835            arg="expressions",
3836            append=append,
3837            dialect=dialect,
3838            into=Expression,
3839            copy=copy,
3840            **opts,
3841        )

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:
3843    def lateral(
3844        self,
3845        *expressions: t.Optional[ExpOrStr],
3846        append: bool = True,
3847        dialect: DialectType = None,
3848        copy: bool = True,
3849        **opts,
3850    ) -> Select:
3851        """
3852        Append to or set the LATERAL expressions.
3853
3854        Example:
3855            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3856            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3857
3858        Args:
3859            *expressions: the SQL code strings to parse.
3860                If an `Expression` instance is passed, it will be used as-is.
3861            append: if `True`, add to any existing expressions.
3862                Otherwise, this resets the expressions.
3863            dialect: the dialect used to parse the input expressions.
3864            copy: if `False`, modify this expression instance in-place.
3865            opts: other options to use to parse the input expressions.
3866
3867        Returns:
3868            The modified Select expression.
3869        """
3870        return _apply_list_builder(
3871            *expressions,
3872            instance=self,
3873            arg="laterals",
3874            append=append,
3875            into=Lateral,
3876            prefix="LATERAL VIEW",
3877            dialect=dialect,
3878            copy=copy,
3879            **opts,
3880        )

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

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:
3980    def where(
3981        self,
3982        *expressions: t.Optional[ExpOrStr],
3983        append: bool = True,
3984        dialect: DialectType = None,
3985        copy: bool = True,
3986        **opts,
3987    ) -> Select:
3988        """
3989        Append to or set the WHERE expressions.
3990
3991        Example:
3992            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3993            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3994
3995        Args:
3996            *expressions: the SQL code strings to parse.
3997                If an `Expression` instance is passed, it will be used as-is.
3998                Multiple expressions are combined with an AND operator.
3999            append: if `True`, AND the new expressions to any existing expression.
4000                Otherwise, this resets the expression.
4001            dialect: the dialect used to parse the input expressions.
4002            copy: if `False`, modify this expression instance in-place.
4003            opts: other options to use to parse the input expressions.
4004
4005        Returns:
4006            Select: the modified expression.
4007        """
4008        return _apply_conjunction_builder(
4009            *expressions,
4010            instance=self,
4011            arg="where",
4012            append=append,
4013            into=Where,
4014            dialect=dialect,
4015            copy=copy,
4016            **opts,
4017        )

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

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:
4058    def window(
4059        self,
4060        *expressions: t.Optional[ExpOrStr],
4061        append: bool = True,
4062        dialect: DialectType = None,
4063        copy: bool = True,
4064        **opts,
4065    ) -> Select:
4066        return _apply_list_builder(
4067            *expressions,
4068            instance=self,
4069            arg="windows",
4070            append=append,
4071            into=Window,
4072            dialect=dialect,
4073            copy=copy,
4074            **opts,
4075        )
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:
4077    def qualify(
4078        self,
4079        *expressions: t.Optional[ExpOrStr],
4080        append: bool = True,
4081        dialect: DialectType = None,
4082        copy: bool = True,
4083        **opts,
4084    ) -> Select:
4085        return _apply_conjunction_builder(
4086            *expressions,
4087            instance=self,
4088            arg="qualify",
4089            append=append,
4090            into=Qualify,
4091            dialect=dialect,
4092            copy=copy,
4093            **opts,
4094        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4096    def distinct(
4097        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4098    ) -> Select:
4099        """
4100        Set the OFFSET expression.
4101
4102        Example:
4103            >>> Select().from_("tbl").select("x").distinct().sql()
4104            'SELECT DISTINCT x FROM tbl'
4105
4106        Args:
4107            ons: the expressions to distinct on
4108            distinct: whether the Select should be distinct
4109            copy: if `False`, modify this expression instance in-place.
4110
4111        Returns:
4112            Select: the modified expression.
4113        """
4114        instance = maybe_copy(self, copy)
4115        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4116        instance.set("distinct", Distinct(on=on) if distinct else None)
4117        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:
4119    def ctas(
4120        self,
4121        table: ExpOrStr,
4122        properties: t.Optional[t.Dict] = None,
4123        dialect: DialectType = None,
4124        copy: bool = True,
4125        **opts,
4126    ) -> Create:
4127        """
4128        Convert this expression to a CREATE TABLE AS statement.
4129
4130        Example:
4131            >>> Select().select("*").from_("tbl").ctas("x").sql()
4132            'CREATE TABLE x AS SELECT * FROM tbl'
4133
4134        Args:
4135            table: the SQL code string to parse as the table name.
4136                If another `Expression` instance is passed, it will be used as-is.
4137            properties: an optional mapping of table properties
4138            dialect: the dialect used to parse the input table.
4139            copy: if `False`, modify this expression instance in-place.
4140            opts: other options to use to parse the input table.
4141
4142        Returns:
4143            The new Create expression.
4144        """
4145        instance = maybe_copy(self, copy)
4146        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4147
4148        properties_expression = None
4149        if properties:
4150            properties_expression = Properties.from_dict(properties)
4151
4152        return Create(
4153            this=table_expression,
4154            kind="TABLE",
4155            expression=instance,
4156            properties=properties_expression,
4157        )

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:
4159    def lock(self, update: bool = True, copy: bool = True) -> Select:
4160        """
4161        Set the locking read mode for this expression.
4162
4163        Examples:
4164            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4165            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4166
4167            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4168            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4169
4170        Args:
4171            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4172            copy: if `False`, modify this expression instance in-place.
4173
4174        Returns:
4175            The modified expression.
4176        """
4177        inst = maybe_copy(self, copy)
4178        inst.set("locks", [Lock(update=update)])
4179
4180        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:
4182    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4183        """
4184        Set hints for this expression.
4185
4186        Examples:
4187            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4188            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4189
4190        Args:
4191            hints: The SQL code strings to parse as the hints.
4192                If an `Expression` instance is passed, it will be used as-is.
4193            dialect: The dialect used to parse the hints.
4194            copy: If `False`, modify this expression instance in-place.
4195
4196        Returns:
4197            The modified expression.
4198        """
4199        inst = maybe_copy(self, copy)
4200        inst.set(
4201            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4202        )
4203
4204        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]
4206    @property
4207    def named_selects(self) -> t.List[str]:
4208        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
4210    @property
4211    def is_star(self) -> bool:
4212        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4214    @property
4215    def selects(self) -> t.List[Expression]:
4216        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4222class Subquery(DerivedTable, Query):
4223    arg_types = {
4224        "this": True,
4225        "alias": False,
4226        "with": False,
4227        **QUERY_MODIFIERS,
4228    }
4229
4230    def unnest(self):
4231        """Returns the first non subquery."""
4232        expression = self
4233        while isinstance(expression, Subquery):
4234            expression = expression.this
4235        return expression
4236
4237    def unwrap(self) -> Subquery:
4238        expression = self
4239        while expression.same_parent and expression.is_wrapper:
4240            expression = t.cast(Subquery, expression.parent)
4241        return expression
4242
4243    def select(
4244        self,
4245        *expressions: t.Optional[ExpOrStr],
4246        append: bool = True,
4247        dialect: DialectType = None,
4248        copy: bool = True,
4249        **opts,
4250    ) -> Subquery:
4251        this = maybe_copy(self, copy)
4252        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4253        return this
4254
4255    @property
4256    def is_wrapper(self) -> bool:
4257        """
4258        Whether this Subquery acts as a simple wrapper around another expression.
4259
4260        SELECT * FROM (((SELECT * FROM t)))
4261                      ^
4262                      This corresponds to a "wrapper" Subquery node
4263        """
4264        return all(v is None for k, v in self.args.items() if k != "this")
4265
4266    @property
4267    def is_star(self) -> bool:
4268        return self.this.is_star
4269
4270    @property
4271    def output_name(self) -> str:
4272        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):
4230    def unnest(self):
4231        """Returns the first non subquery."""
4232        expression = self
4233        while isinstance(expression, Subquery):
4234            expression = expression.this
4235        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4237    def unwrap(self) -> Subquery:
4238        expression = self
4239        while expression.same_parent and expression.is_wrapper:
4240            expression = t.cast(Subquery, expression.parent)
4241        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:
4243    def select(
4244        self,
4245        *expressions: t.Optional[ExpOrStr],
4246        append: bool = True,
4247        dialect: DialectType = None,
4248        copy: bool = True,
4249        **opts,
4250    ) -> Subquery:
4251        this = maybe_copy(self, copy)
4252        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4253        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
4255    @property
4256    def is_wrapper(self) -> bool:
4257        """
4258        Whether this Subquery acts as a simple wrapper around another expression.
4259
4260        SELECT * FROM (((SELECT * FROM t)))
4261                      ^
4262                      This corresponds to a "wrapper" Subquery node
4263        """
4264        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
4266    @property
4267    def is_star(self) -> bool:
4268        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4270    @property
4271    def output_name(self) -> str:
4272        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):
4275class TableSample(Expression):
4276    arg_types = {
4277        "expressions": False,
4278        "method": False,
4279        "bucket_numerator": False,
4280        "bucket_denominator": False,
4281        "bucket_field": False,
4282        "percent": False,
4283        "rows": False,
4284        "size": False,
4285        "seed": False,
4286    }
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):
4289class Tag(Expression):
4290    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4291
4292    arg_types = {
4293        "this": False,
4294        "prefix": False,
4295        "postfix": False,
4296    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4301class Pivot(Expression):
4302    arg_types = {
4303        "this": False,
4304        "alias": False,
4305        "expressions": False,
4306        "field": False,
4307        "unpivot": False,
4308        "using": False,
4309        "group": False,
4310        "columns": False,
4311        "include_nulls": False,
4312        "default_on_null": False,
4313        "into": False,
4314    }
4315
4316    @property
4317    def unpivot(self) -> bool:
4318        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4316    @property
4317    def unpivot(self) -> bool:
4318        return bool(self.args.get("unpivot"))
key = 'pivot'
class UnpivotColumns(Expression):
4323class UnpivotColumns(Expression):
4324    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4327class Window(Condition):
4328    arg_types = {
4329        "this": True,
4330        "partition_by": False,
4331        "order": False,
4332        "spec": False,
4333        "alias": False,
4334        "over": False,
4335        "first": False,
4336    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4339class WindowSpec(Expression):
4340    arg_types = {
4341        "kind": False,
4342        "start": False,
4343        "start_side": False,
4344        "end": False,
4345        "end_side": False,
4346    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4349class PreWhere(Expression):
4350    pass
key = 'prewhere'
class Where(Expression):
4353class Where(Expression):
4354    pass
key = 'where'
class Star(Expression):
4357class Star(Expression):
4358    arg_types = {"except": False, "replace": False, "rename": False}
4359
4360    @property
4361    def name(self) -> str:
4362        return "*"
4363
4364    @property
4365    def output_name(self) -> str:
4366        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4360    @property
4361    def name(self) -> str:
4362        return "*"
output_name: str
4364    @property
4365    def output_name(self) -> str:
4366        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):
4369class Parameter(Condition):
4370    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4373class SessionParameter(Condition):
4374    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4377class Placeholder(Condition):
4378    arg_types = {"this": False, "kind": False}
4379
4380    @property
4381    def name(self) -> str:
4382        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4380    @property
4381    def name(self) -> str:
4382        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4385class Null(Condition):
4386    arg_types: t.Dict[str, t.Any] = {}
4387
4388    @property
4389    def name(self) -> str:
4390        return "NULL"
4391
4392    def to_py(self) -> Lit[None]:
4393        return None
arg_types: Dict[str, Any] = {}
name: str
4388    @property
4389    def name(self) -> str:
4390        return "NULL"
def to_py(self) -> Literal[None]:
4392    def to_py(self) -> Lit[None]:
4393        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4396class Boolean(Condition):
4397    def to_py(self) -> bool:
4398        return self.this
def to_py(self) -> bool:
4397    def to_py(self) -> bool:
4398        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
4917    @property
4918    def name(self) -> str:
4919        return self.expression.name
output_name: str
4921    @property
4922    def output_name(self) -> str:
4923        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:
4925    @classmethod
4926    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4927        """Build a Dot object with a sequence of expressions."""
4928        if len(expressions) < 2:
4929            raise ValueError("Dot requires >= 2 expressions.")
4930
4931        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]
4933    @property
4934    def parts(self) -> t.List[Expression]:
4935        """Return the parts of a table / column in order catalog, db, table."""
4936        this, *parts = self.flatten()
4937
4938        parts.reverse()
4939
4940        for arg in COLUMN_PARTS:
4941            part = this.args.get(arg)
4942
4943            if isinstance(part, Expression):
4944                parts.append(part)
4945
4946        parts.reverse()
4947        return parts

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

key = 'dot'
class DPipe(Binary):
4950class DPipe(Binary):
4951    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4954class EQ(Binary, Predicate):
4955    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4958class NullSafeEQ(Binary, Predicate):
4959    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4962class NullSafeNEQ(Binary, Predicate):
4963    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4967class PropertyEQ(Binary):
4968    pass
key = 'propertyeq'
class Distance(Binary):
4971class Distance(Binary):
4972    pass
key = 'distance'
class Escape(Binary):
4975class Escape(Binary):
4976    pass
key = 'escape'
class Glob(Binary, Predicate):
4979class Glob(Binary, Predicate):
4980    pass
key = 'glob'
class GT(Binary, Predicate):
4983class GT(Binary, Predicate):
4984    pass
key = 'gt'
class GTE(Binary, Predicate):
4987class GTE(Binary, Predicate):
4988    pass
key = 'gte'
class ILike(Binary, Predicate):
4991class ILike(Binary, Predicate):
4992    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4995class ILikeAny(Binary, Predicate):
4996    pass
key = 'ilikeany'
class IntDiv(Binary):
4999class IntDiv(Binary):
5000    pass
key = 'intdiv'
class Is(Binary, Predicate):
5003class Is(Binary, Predicate):
5004    pass
key = 'is'
class Kwarg(Binary):
5007class Kwarg(Binary):
5008    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5011class Like(Binary, Predicate):
5012    pass
key = 'like'
class LikeAny(Binary, Predicate):
5015class LikeAny(Binary, Predicate):
5016    pass
key = 'likeany'
class LT(Binary, Predicate):
5019class LT(Binary, Predicate):
5020    pass
key = 'lt'
class LTE(Binary, Predicate):
5023class LTE(Binary, Predicate):
5024    pass
key = 'lte'
class Mod(Binary):
5027class Mod(Binary):
5028    pass
key = 'mod'
class Mul(Binary):
5031class Mul(Binary):
5032    pass
key = 'mul'
class NEQ(Binary, Predicate):
5035class NEQ(Binary, Predicate):
5036    pass
key = 'neq'
class Operator(Binary):
5040class Operator(Binary):
5041    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5044class SimilarTo(Binary, Predicate):
5045    pass
key = 'similarto'
class Slice(Binary):
5048class Slice(Binary):
5049    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5052class Sub(Binary):
5053    pass
key = 'sub'
class Unary(Condition):
5058class Unary(Condition):
5059    pass
key = 'unary'
class BitwiseNot(Unary):
5062class BitwiseNot(Unary):
5063    pass
key = 'bitwisenot'
class Not(Unary):
5066class Not(Unary):
5067    pass
key = 'not'
class Paren(Unary):
5070class Paren(Unary):
5071    @property
5072    def output_name(self) -> str:
5073        return self.this.name
output_name: str
5071    @property
5072    def output_name(self) -> str:
5073        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):
5076class Neg(Unary):
5077    def to_py(self) -> int | Decimal:
5078        if self.is_number:
5079            return self.this.to_py() * -1
5080        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5077    def to_py(self) -> int | Decimal:
5078        if self.is_number:
5079            return self.this.to_py() * -1
5080        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5083class Alias(Expression):
5084    arg_types = {"this": True, "alias": False}
5085
5086    @property
5087    def output_name(self) -> str:
5088        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5086    @property
5087    def output_name(self) -> str:
5088        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):
5093class PivotAlias(Alias):
5094    pass
key = 'pivotalias'
class PivotAny(Expression):
5099class PivotAny(Expression):
5100    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5103class Aliases(Expression):
5104    arg_types = {"this": True, "expressions": True}
5105
5106    @property
5107    def aliases(self):
5108        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5106    @property
5107    def aliases(self):
5108        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5112class AtIndex(Expression):
5113    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5116class AtTimeZone(Expression):
5117    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5120class FromTimeZone(Expression):
5121    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5124class Between(Predicate):
5125    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5128class Bracket(Condition):
5129    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5130    arg_types = {
5131        "this": True,
5132        "expressions": True,
5133        "offset": False,
5134        "safe": False,
5135        "returns_list_for_maps": False,
5136    }
5137
5138    @property
5139    def output_name(self) -> str:
5140        if len(self.expressions) == 1:
5141            return self.expressions[0].output_name
5142
5143        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5138    @property
5139    def output_name(self) -> str:
5140        if len(self.expressions) == 1:
5141            return self.expressions[0].output_name
5142
5143        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):
5146class Distinct(Expression):
5147    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5150class In(Predicate):
5151    arg_types = {
5152        "this": True,
5153        "expressions": False,
5154        "query": False,
5155        "unnest": False,
5156        "field": False,
5157        "is_global": False,
5158    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5162class ForIn(Expression):
5163    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5166class TimeUnit(Expression):
5167    """Automatically converts unit arg into a var."""
5168
5169    arg_types = {"unit": False}
5170
5171    UNABBREVIATED_UNIT_NAME = {
5172        "D": "DAY",
5173        "H": "HOUR",
5174        "M": "MINUTE",
5175        "MS": "MILLISECOND",
5176        "NS": "NANOSECOND",
5177        "Q": "QUARTER",
5178        "S": "SECOND",
5179        "US": "MICROSECOND",
5180        "W": "WEEK",
5181        "Y": "YEAR",
5182    }
5183
5184    VAR_LIKE = (Column, Literal, Var)
5185
5186    def __init__(self, **args):
5187        unit = args.get("unit")
5188        if isinstance(unit, self.VAR_LIKE):
5189            args["unit"] = Var(
5190                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5191            )
5192        elif isinstance(unit, Week):
5193            unit.set("this", Var(this=unit.this.name.upper()))
5194
5195        super().__init__(**args)
5196
5197    @property
5198    def unit(self) -> t.Optional[Var | IntervalSpan]:
5199        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5186    def __init__(self, **args):
5187        unit = args.get("unit")
5188        if isinstance(unit, self.VAR_LIKE):
5189            args["unit"] = Var(
5190                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5191            )
5192        elif isinstance(unit, Week):
5193            unit.set("this", Var(this=unit.this.name.upper()))
5194
5195        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]
5197    @property
5198    def unit(self) -> t.Optional[Var | IntervalSpan]:
5199        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5202class IntervalOp(TimeUnit):
5203    arg_types = {"unit": False, "expression": True}
5204
5205    def interval(self):
5206        return Interval(
5207            this=self.expression.copy(),
5208            unit=self.unit.copy() if self.unit else None,
5209        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5205    def interval(self):
5206        return Interval(
5207            this=self.expression.copy(),
5208            unit=self.unit.copy() if self.unit else None,
5209        )
key = 'intervalop'
class IntervalSpan(DataType):
5215class IntervalSpan(DataType):
5216    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5219class Interval(TimeUnit):
5220    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5223class IgnoreNulls(Expression):
5224    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5227class RespectNulls(Expression):
5228    pass
key = 'respectnulls'
class HavingMax(Expression):
5232class HavingMax(Expression):
5233    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5237class Func(Condition):
5238    """
5239    The base class for all function expressions.
5240
5241    Attributes:
5242        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5243            treated as a variable length argument and the argument's value will be stored as a list.
5244        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5245            function expression. These values are used to map this node to a name during parsing as
5246            well as to provide the function's name during SQL string generation. By default the SQL
5247            name is set to the expression's class name transformed to snake case.
5248    """
5249
5250    is_var_len_args = False
5251
5252    @classmethod
5253    def from_arg_list(cls, args):
5254        if cls.is_var_len_args:
5255            all_arg_keys = list(cls.arg_types)
5256            # If this function supports variable length argument treat the last argument as such.
5257            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5258            num_non_var = len(non_var_len_arg_keys)
5259
5260            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5261            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5262        else:
5263            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5264
5265        return cls(**args_dict)
5266
5267    @classmethod
5268    def sql_names(cls):
5269        if cls is Func:
5270            raise NotImplementedError(
5271                "SQL name is only supported by concrete function implementations"
5272            )
5273        if "_sql_names" not in cls.__dict__:
5274            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5275        return cls._sql_names
5276
5277    @classmethod
5278    def sql_name(cls):
5279        return cls.sql_names()[0]
5280
5281    @classmethod
5282    def default_parser_mappings(cls):
5283        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):
5252    @classmethod
5253    def from_arg_list(cls, args):
5254        if cls.is_var_len_args:
5255            all_arg_keys = list(cls.arg_types)
5256            # If this function supports variable length argument treat the last argument as such.
5257            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5258            num_non_var = len(non_var_len_arg_keys)
5259
5260            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5261            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5262        else:
5263            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5264
5265        return cls(**args_dict)
@classmethod
def sql_names(cls):
5267    @classmethod
5268    def sql_names(cls):
5269        if cls is Func:
5270            raise NotImplementedError(
5271                "SQL name is only supported by concrete function implementations"
5272            )
5273        if "_sql_names" not in cls.__dict__:
5274            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5275        return cls._sql_names
@classmethod
def sql_name(cls):
5277    @classmethod
5278    def sql_name(cls):
5279        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5281    @classmethod
5282    def default_parser_mappings(cls):
5283        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5286class AggFunc(Func):
5287    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5290class ParameterizedAgg(AggFunc):
5291    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5294class Abs(Func):
5295    pass
key = 'abs'
class ArgMax(AggFunc):
5298class ArgMax(AggFunc):
5299    arg_types = {"this": True, "expression": True, "count": False}
5300    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5303class ArgMin(AggFunc):
5304    arg_types = {"this": True, "expression": True, "count": False}
5305    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5308class ApproxTopK(AggFunc):
5309    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5312class Flatten(Func):
5313    pass
key = 'flatten'
class Transform(Func):
5317class Transform(Func):
5318    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5321class Anonymous(Func):
5322    arg_types = {"this": True, "expressions": False}
5323    is_var_len_args = True
5324
5325    @property
5326    def name(self) -> str:
5327        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
5325    @property
5326    def name(self) -> str:
5327        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5330class AnonymousAggFunc(AggFunc):
5331    arg_types = {"this": True, "expressions": False}
5332    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5336class CombinedAggFunc(AnonymousAggFunc):
5337    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5340class CombinedParameterizedAgg(ParameterizedAgg):
5341    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5346class Hll(AggFunc):
5347    arg_types = {"this": True, "expressions": False}
5348    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5351class ApproxDistinct(AggFunc):
5352    arg_types = {"this": True, "accuracy": False}
5353    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5356class Apply(Func):
5357    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5360class Array(Func):
5361    arg_types = {"expressions": False, "bracket_notation": False}
5362    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5366class ToArray(Func):
5367    pass
key = 'toarray'
class List(Func):
5371class List(Func):
5372    arg_types = {"expressions": False}
5373    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5377class Pad(Func):
5378    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):
5383class ToChar(Func):
5384    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5389class ToNumber(Func):
5390    arg_types = {
5391        "this": True,
5392        "format": False,
5393        "nlsparam": False,
5394        "precision": False,
5395        "scale": False,
5396    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5400class ToDouble(Func):
5401    arg_types = {
5402        "this": True,
5403        "format": False,
5404    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5407class Columns(Func):
5408    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5412class Convert(Func):
5413    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5416class ConvertTimezone(Func):
5417    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):
5420class GenerateSeries(Func):
5421    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):
5427class ExplodingGenerateSeries(GenerateSeries):
5428    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5431class ArrayAgg(AggFunc):
5432    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5435class ArrayUniqueAgg(AggFunc):
5436    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5439class ArrayAll(Func):
5440    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5444class ArrayAny(Func):
5445    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5448class ArrayConcat(Func):
5449    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5450    arg_types = {"this": True, "expressions": False}
5451    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5454class ArrayConstructCompact(Func):
5455    arg_types = {"expressions": True}
5456    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5459class ArrayContains(Binary, Func):
5460    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5463class ArrayContainsAll(Binary, Func):
5464    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5467class ArrayFilter(Func):
5468    arg_types = {"this": True, "expression": True}
5469    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5472class ArrayToString(Func):
5473    arg_types = {"this": True, "expression": True, "null": False}
5474    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5478class String(Func):
5479    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5482class StringToArray(Func):
5483    arg_types = {"this": True, "expression": True, "null": False}
5484    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5487class ArrayOverlaps(Binary, Func):
5488    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5491class ArraySize(Func):
5492    arg_types = {"this": True, "expression": False}
5493    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5496class ArraySort(Func):
5497    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5500class ArraySum(Func):
5501    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5504class ArrayUnionAgg(AggFunc):
5505    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5508class Avg(AggFunc):
5509    pass
key = 'avg'
class AnyValue(AggFunc):
5512class AnyValue(AggFunc):
5513    pass
key = 'anyvalue'
class Lag(AggFunc):
5516class Lag(AggFunc):
5517    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5520class Lead(AggFunc):
5521    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5526class First(AggFunc):
5527    pass
key = 'first'
class Last(AggFunc):
5530class Last(AggFunc):
5531    pass
key = 'last'
class FirstValue(AggFunc):
5534class FirstValue(AggFunc):
5535    pass
key = 'firstvalue'
class LastValue(AggFunc):
5538class LastValue(AggFunc):
5539    pass
key = 'lastvalue'
class NthValue(AggFunc):
5542class NthValue(AggFunc):
5543    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5546class Case(Func):
5547    arg_types = {"this": False, "ifs": True, "default": False}
5548
5549    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5550        instance = maybe_copy(self, copy)
5551        instance.append(
5552            "ifs",
5553            If(
5554                this=maybe_parse(condition, copy=copy, **opts),
5555                true=maybe_parse(then, copy=copy, **opts),
5556            ),
5557        )
5558        return instance
5559
5560    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5561        instance = maybe_copy(self, copy)
5562        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5563        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:
5549    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5550        instance = maybe_copy(self, copy)
5551        instance.append(
5552            "ifs",
5553            If(
5554                this=maybe_parse(condition, copy=copy, **opts),
5555                true=maybe_parse(then, copy=copy, **opts),
5556            ),
5557        )
5558        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5560    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5561        instance = maybe_copy(self, copy)
5562        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5563        return instance
key = 'case'
class Cast(Func):
5566class Cast(Func):
5567    arg_types = {
5568        "this": True,
5569        "to": True,
5570        "format": False,
5571        "safe": False,
5572        "action": False,
5573        "default": False,
5574    }
5575
5576    @property
5577    def name(self) -> str:
5578        return self.this.name
5579
5580    @property
5581    def to(self) -> DataType:
5582        return self.args["to"]
5583
5584    @property
5585    def output_name(self) -> str:
5586        return self.name
5587
5588    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5589        """
5590        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5591        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5592        array<int> != array<float>.
5593
5594        Args:
5595            dtypes: the data types to compare this Cast's DataType to.
5596
5597        Returns:
5598            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5599        """
5600        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5576    @property
5577    def name(self) -> str:
5578        return self.this.name
to: DataType
5580    @property
5581    def to(self) -> DataType:
5582        return self.args["to"]
output_name: str
5584    @property
5585    def output_name(self) -> str:
5586        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:
5588    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5589        """
5590        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5591        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5592        array<int> != array<float>.
5593
5594        Args:
5595            dtypes: the data types to compare this Cast's DataType to.
5596
5597        Returns:
5598            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5599        """
5600        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):
5603class TryCast(Cast):
5604    pass
key = 'trycast'
class JSONCast(Cast):
5608class JSONCast(Cast):
5609    pass
key = 'jsoncast'
class Try(Func):
5612class Try(Func):
5613    pass
key = 'try'
class CastToStrType(Func):
5616class CastToStrType(Func):
5617    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5620class Collate(Binary, Func):
5621    pass
key = 'collate'
class Ceil(Func):
5624class Ceil(Func):
5625    arg_types = {"this": True, "decimals": False, "to": False}
5626    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5629class Coalesce(Func):
5630    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5631    is_var_len_args = True
5632    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5635class Chr(Func):
5636    arg_types = {"expressions": True, "charset": False}
5637    is_var_len_args = True
5638    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5641class Concat(Func):
5642    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5643    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5646class ConcatWs(Concat):
5647    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5650class Contains(Func):
5651    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5655class ConnectByRoot(Func):
5656    pass
key = 'connectbyroot'
class Count(AggFunc):
5659class Count(AggFunc):
5660    arg_types = {"this": False, "expressions": False, "big_int": False}
5661    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5664class CountIf(AggFunc):
5665    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5669class Cbrt(Func):
5670    pass
key = 'cbrt'
class CurrentDate(Func):
5673class CurrentDate(Func):
5674    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5677class CurrentDatetime(Func):
5678    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5681class CurrentTime(Func):
5682    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5685class CurrentTimestamp(Func):
5686    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5689class CurrentSchema(Func):
5690    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5693class CurrentUser(Func):
5694    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5697class DateAdd(Func, IntervalOp):
5698    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5701class DateBin(Func, IntervalOp):
5702    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):
5705class DateSub(Func, IntervalOp):
5706    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5709class DateDiff(Func, TimeUnit):
5710    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5711    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5714class DateTrunc(Func):
5715    arg_types = {"unit": True, "this": True, "zone": False}
5716
5717    def __init__(self, **args):
5718        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5719        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5720        unabbreviate = args.pop("unabbreviate", True)
5721
5722        unit = args.get("unit")
5723        if isinstance(unit, TimeUnit.VAR_LIKE):
5724            unit_name = unit.name.upper()
5725            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5726                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5727
5728            args["unit"] = Literal.string(unit_name)
5729        elif isinstance(unit, Week):
5730            unit.set("this", Literal.string(unit.this.name.upper()))
5731
5732        super().__init__(**args)
5733
5734    @property
5735    def unit(self) -> Expression:
5736        return self.args["unit"]
DateTrunc(**args)
5717    def __init__(self, **args):
5718        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5719        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5720        unabbreviate = args.pop("unabbreviate", True)
5721
5722        unit = args.get("unit")
5723        if isinstance(unit, TimeUnit.VAR_LIKE):
5724            unit_name = unit.name.upper()
5725            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5726                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5727
5728            args["unit"] = Literal.string(unit_name)
5729        elif isinstance(unit, Week):
5730            unit.set("this", Literal.string(unit.this.name.upper()))
5731
5732        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5734    @property
5735    def unit(self) -> Expression:
5736        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5741class Datetime(Func):
5742    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5745class DatetimeAdd(Func, IntervalOp):
5746    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5749class DatetimeSub(Func, IntervalOp):
5750    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5753class DatetimeDiff(Func, TimeUnit):
5754    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5757class DatetimeTrunc(Func, TimeUnit):
5758    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5761class DayOfWeek(Func):
5762    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5767class DayOfWeekIso(Func):
5768    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5771class DayOfMonth(Func):
5772    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5775class DayOfYear(Func):
5776    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5779class ToDays(Func):
5780    pass
key = 'todays'
class WeekOfYear(Func):
5783class WeekOfYear(Func):
5784    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5787class MonthsBetween(Func):
5788    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5791class MakeInterval(Func):
5792    arg_types = {
5793        "year": False,
5794        "month": False,
5795        "day": False,
5796        "hour": False,
5797        "minute": False,
5798        "second": False,
5799    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5802class LastDay(Func, TimeUnit):
5803    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5804    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5807class Extract(Func):
5808    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5811class Exists(Func, SubqueryPredicate):
5812    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5815class Timestamp(Func):
5816    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5819class TimestampAdd(Func, TimeUnit):
5820    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5823class TimestampSub(Func, TimeUnit):
5824    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5827class TimestampDiff(Func, TimeUnit):
5828    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5829    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5832class TimestampTrunc(Func, TimeUnit):
5833    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5836class TimeAdd(Func, TimeUnit):
5837    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5840class TimeSub(Func, TimeUnit):
5841    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5844class TimeDiff(Func, TimeUnit):
5845    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5848class TimeTrunc(Func, TimeUnit):
5849    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5852class DateFromParts(Func):
5853    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5854    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5857class TimeFromParts(Func):
5858    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5859    arg_types = {
5860        "hour": True,
5861        "min": True,
5862        "sec": True,
5863        "nano": False,
5864        "fractions": False,
5865        "precision": False,
5866    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5869class DateStrToDate(Func):
5870    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5873class DateToDateStr(Func):
5874    pass
key = 'datetodatestr'
class DateToDi(Func):
5877class DateToDi(Func):
5878    pass
key = 'datetodi'
class Date(Func):
5882class Date(Func):
5883    arg_types = {"this": False, "zone": False, "expressions": False}
5884    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5887class Day(Func):
5888    pass
key = 'day'
class Decode(Func):
5891class Decode(Func):
5892    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5895class DiToDate(Func):
5896    pass
key = 'ditodate'
class Encode(Func):
5899class Encode(Func):
5900    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5903class Exp(Func):
5904    pass
key = 'exp'
class Explode(Func, UDTF):
5908class Explode(Func, UDTF):
5909    arg_types = {"this": True, "expressions": False}
5910    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5914class Inline(Func):
5915    pass
key = 'inline'
class ExplodeOuter(Explode):
5918class ExplodeOuter(Explode):
5919    pass
key = 'explodeouter'
class Posexplode(Explode):
5922class Posexplode(Explode):
5923    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5926class PosexplodeOuter(Posexplode, ExplodeOuter):
5927    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5930class Unnest(Func, UDTF):
5931    arg_types = {
5932        "expressions": True,
5933        "alias": False,
5934        "offset": False,
5935        "explode_array": False,
5936    }
5937
5938    @property
5939    def selects(self) -> t.List[Expression]:
5940        columns = super().selects
5941        offset = self.args.get("offset")
5942        if offset:
5943            columns = columns + [to_identifier("offset") if offset is True else offset]
5944        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5938    @property
5939    def selects(self) -> t.List[Expression]:
5940        columns = super().selects
5941        offset = self.args.get("offset")
5942        if offset:
5943            columns = columns + [to_identifier("offset") if offset is True else offset]
5944        return columns
key = 'unnest'
class Floor(Func):
5947class Floor(Func):
5948    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5951class FromBase64(Func):
5952    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5955class FeaturesAtTime(Func):
5956    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):
5959class ToBase64(Func):
5960    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5964class FromISO8601Timestamp(Func):
5965    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5968class GapFill(Func):
5969    arg_types = {
5970        "this": True,
5971        "ts_column": True,
5972        "bucket_width": True,
5973        "partitioning_columns": False,
5974        "value_columns": False,
5975        "origin": False,
5976        "ignore_nulls": False,
5977    }
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):
5981class GenerateDateArray(Func):
5982    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5986class GenerateTimestampArray(Func):
5987    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5990class Greatest(Func):
5991    arg_types = {"this": True, "expressions": False}
5992    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5997class OverflowTruncateBehavior(Expression):
5998    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6001class GroupConcat(AggFunc):
6002    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6005class Hex(Func):
6006    pass
key = 'hex'
class LowerHex(Hex):
6009class LowerHex(Hex):
6010    pass
key = 'lowerhex'
class And(Connector, Func):
6013class And(Connector, Func):
6014    pass
key = 'and'
class Or(Connector, Func):
6017class Or(Connector, Func):
6018    pass
key = 'or'
class Xor(Connector, Func):
6021class Xor(Connector, Func):
6022    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6025class If(Func):
6026    arg_types = {"this": True, "true": True, "false": False}
6027    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6030class Nullif(Func):
6031    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6034class Initcap(Func):
6035    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6038class IsAscii(Func):
6039    pass
key = 'isascii'
class IsNan(Func):
6042class IsNan(Func):
6043    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6047class Int64(Func):
6048    pass
key = 'int64'
class IsInf(Func):
6051class IsInf(Func):
6052    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6056class JSON(Expression):
6057    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6060class JSONPath(Expression):
6061    arg_types = {"expressions": True, "escape": False}
6062
6063    @property
6064    def output_name(self) -> str:
6065        last_segment = self.expressions[-1].this
6066        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6063    @property
6064    def output_name(self) -> str:
6065        last_segment = self.expressions[-1].this
6066        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):
6069class JSONPathPart(Expression):
6070    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6073class JSONPathFilter(JSONPathPart):
6074    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6077class JSONPathKey(JSONPathPart):
6078    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6081class JSONPathRecursive(JSONPathPart):
6082    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6085class JSONPathRoot(JSONPathPart):
6086    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6089class JSONPathScript(JSONPathPart):
6090    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6093class JSONPathSlice(JSONPathPart):
6094    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6097class JSONPathSelector(JSONPathPart):
6098    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6101class JSONPathSubscript(JSONPathPart):
6102    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6105class JSONPathUnion(JSONPathPart):
6106    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6109class JSONPathWildcard(JSONPathPart):
6110    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6113class FormatJson(Expression):
6114    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6117class JSONKeyValue(Expression):
6118    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6121class JSONObject(Func):
6122    arg_types = {
6123        "expressions": False,
6124        "null_handling": False,
6125        "unique_keys": False,
6126        "return_type": False,
6127        "encoding": False,
6128    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6131class JSONObjectAgg(AggFunc):
6132    arg_types = {
6133        "expressions": False,
6134        "null_handling": False,
6135        "unique_keys": False,
6136        "return_type": False,
6137        "encoding": False,
6138    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6142class JSONBObjectAgg(AggFunc):
6143    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6147class JSONArray(Func):
6148    arg_types = {
6149        "expressions": True,
6150        "null_handling": False,
6151        "return_type": False,
6152        "strict": False,
6153    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6157class JSONArrayAgg(Func):
6158    arg_types = {
6159        "this": True,
6160        "order": False,
6161        "null_handling": False,
6162        "return_type": False,
6163        "strict": False,
6164    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6167class JSONExists(Func):
6168    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):
6173class JSONColumnDef(Expression):
6174    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):
6177class JSONSchema(Expression):
6178    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6182class JSONValue(Expression):
6183    arg_types = {
6184        "this": True,
6185        "path": True,
6186        "returning": False,
6187        "on_condition": False,
6188    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6191class JSONValueArray(Func):
6192    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6196class JSONTable(Func):
6197    arg_types = {
6198        "this": True,
6199        "schema": True,
6200        "path": False,
6201        "error_handling": False,
6202        "empty_handling": False,
6203    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6207class ObjectInsert(Func):
6208    arg_types = {
6209        "this": True,
6210        "key": True,
6211        "value": True,
6212        "update_flag": False,
6213    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6216class OpenJSONColumnDef(Expression):
6217    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):
6220class OpenJSON(Func):
6221    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6224class JSONBContains(Binary, Func):
6225    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6228class JSONBExists(Func):
6229    arg_types = {"this": True, "path": True}
6230    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6233class JSONExtract(Binary, Func):
6234    arg_types = {
6235        "this": True,
6236        "expression": True,
6237        "only_json_types": False,
6238        "expressions": False,
6239        "variant_extract": False,
6240        "json_query": False,
6241        "option": False,
6242        "quote": False,
6243        "on_condition": False,
6244    }
6245    _sql_names = ["JSON_EXTRACT"]
6246    is_var_len_args = True
6247
6248    @property
6249    def output_name(self) -> str:
6250        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
6248    @property
6249    def output_name(self) -> str:
6250        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):
6254class JSONExtractQuote(Expression):
6255    arg_types = {
6256        "option": True,
6257        "scalar": False,
6258    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6261class JSONExtractArray(Func):
6262    arg_types = {"this": True, "expression": False}
6263    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6266class JSONExtractScalar(Binary, Func):
6267    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6268    _sql_names = ["JSON_EXTRACT_SCALAR"]
6269    is_var_len_args = True
6270
6271    @property
6272    def output_name(self) -> str:
6273        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
6271    @property
6272    def output_name(self) -> str:
6273        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):
6276class JSONBExtract(Binary, Func):
6277    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6280class JSONBExtractScalar(Binary, Func):
6281    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6284class JSONFormat(Func):
6285    arg_types = {"this": False, "options": False}
6286    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6290class JSONArrayContains(Binary, Predicate, Func):
6291    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6294class ParseJSON(Func):
6295    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6296    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6297    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6298    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6301class Least(Func):
6302    arg_types = {"this": True, "expressions": False}
6303    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6306class Left(Func):
6307    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6314class Length(Func):
6315    arg_types = {"this": True, "binary": False, "encoding": False}
6316    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6319class Levenshtein(Func):
6320    arg_types = {
6321        "this": True,
6322        "expression": False,
6323        "ins_cost": False,
6324        "del_cost": False,
6325        "sub_cost": False,
6326        "max_dist": False,
6327    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6330class Ln(Func):
6331    pass
key = 'ln'
class Log(Func):
6334class Log(Func):
6335    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6338class LogicalOr(AggFunc):
6339    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6342class LogicalAnd(AggFunc):
6343    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6346class Lower(Func):
6347    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6350class Map(Func):
6351    arg_types = {"keys": False, "values": False}
6352
6353    @property
6354    def keys(self) -> t.List[Expression]:
6355        keys = self.args.get("keys")
6356        return keys.expressions if keys else []
6357
6358    @property
6359    def values(self) -> t.List[Expression]:
6360        values = self.args.get("values")
6361        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6353    @property
6354    def keys(self) -> t.List[Expression]:
6355        keys = self.args.get("keys")
6356        return keys.expressions if keys else []
values: List[Expression]
6358    @property
6359    def values(self) -> t.List[Expression]:
6360        values = self.args.get("values")
6361        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6365class ToMap(Func):
6366    pass
key = 'tomap'
class MapFromEntries(Func):
6369class MapFromEntries(Func):
6370    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6374class ScopeResolution(Expression):
6375    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6378class Stream(Expression):
6379    pass
key = 'stream'
class StarMap(Func):
6382class StarMap(Func):
6383    pass
key = 'starmap'
class VarMap(Func):
6386class VarMap(Func):
6387    arg_types = {"keys": True, "values": True}
6388    is_var_len_args = True
6389
6390    @property
6391    def keys(self) -> t.List[Expression]:
6392        return self.args["keys"].expressions
6393
6394    @property
6395    def values(self) -> t.List[Expression]:
6396        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6390    @property
6391    def keys(self) -> t.List[Expression]:
6392        return self.args["keys"].expressions
values: List[Expression]
6394    @property
6395    def values(self) -> t.List[Expression]:
6396        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6400class MatchAgainst(Func):
6401    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6404class Max(AggFunc):
6405    arg_types = {"this": True, "expressions": False}
6406    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6409class MD5(Func):
6410    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6414class MD5Digest(Func):
6415    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6418class Median(AggFunc):
6419    pass
key = 'median'
class Min(AggFunc):
6422class Min(AggFunc):
6423    arg_types = {"this": True, "expressions": False}
6424    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6427class Month(Func):
6428    pass
key = 'month'
class AddMonths(Func):
6431class AddMonths(Func):
6432    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6435class Nvl2(Func):
6436    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6439class Normalize(Func):
6440    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6443class Overlay(Func):
6444    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):
6448class Predict(Func):
6449    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6452class Pow(Binary, Func):
6453    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6456class PercentileCont(AggFunc):
6457    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6460class PercentileDisc(AggFunc):
6461    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6464class Quantile(AggFunc):
6465    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6468class ApproxQuantile(Quantile):
6469    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):
6472class Quarter(Func):
6473    pass
key = 'quarter'
class Rand(Func):
6478class Rand(Func):
6479    _sql_names = ["RAND", "RANDOM"]
6480    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6483class Randn(Func):
6484    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6487class RangeN(Func):
6488    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6491class ReadCSV(Func):
6492    _sql_names = ["READ_CSV"]
6493    is_var_len_args = True
6494    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6497class Reduce(Func):
6498    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):
6501class RegexpExtract(Func):
6502    arg_types = {
6503        "this": True,
6504        "expression": True,
6505        "position": False,
6506        "occurrence": False,
6507        "parameters": False,
6508        "group": False,
6509    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6512class RegexpExtractAll(Func):
6513    arg_types = {
6514        "this": True,
6515        "expression": True,
6516        "position": False,
6517        "occurrence": False,
6518        "parameters": False,
6519        "group": False,
6520    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6523class RegexpReplace(Func):
6524    arg_types = {
6525        "this": True,
6526        "expression": True,
6527        "replacement": False,
6528        "position": False,
6529        "occurrence": False,
6530        "modifiers": False,
6531    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6534class RegexpLike(Binary, Func):
6535    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6538class RegexpILike(Binary, Func):
6539    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6544class RegexpSplit(Func):
6545    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6548class Repeat(Func):
6549    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6554class Round(Func):
6555    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6558class RowNumber(Func):
6559    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6562class SafeDivide(Func):
6563    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6566class SHA(Func):
6567    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6570class SHA2(Func):
6571    _sql_names = ["SHA2"]
6572    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6575class Sign(Func):
6576    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6579class SortArray(Func):
6580    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6583class Split(Func):
6584    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6588class SplitPart(Func):
6589    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6594class Substring(Func):
6595    _sql_names = ["SUBSTRING", "SUBSTR"]
6596    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6599class StandardHash(Func):
6600    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6603class StartsWith(Func):
6604    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6605    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6608class StrPosition(Func):
6609    arg_types = {
6610        "this": True,
6611        "substr": True,
6612        "position": False,
6613        "occurrence": False,
6614    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6617class StrToDate(Func):
6618    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6621class StrToTime(Func):
6622    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):
6627class StrToUnix(Func):
6628    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6633class StrToMap(Func):
6634    arg_types = {
6635        "this": True,
6636        "pair_delim": False,
6637        "key_value_delim": False,
6638        "duplicate_resolution_callback": False,
6639    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6642class NumberToStr(Func):
6643    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6646class FromBase(Func):
6647    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6650class Struct(Func):
6651    arg_types = {"expressions": False}
6652    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6655class StructExtract(Func):
6656    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6661class Stuff(Func):
6662    _sql_names = ["STUFF", "INSERT"]
6663    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):
6666class Sum(AggFunc):
6667    pass
key = 'sum'
class Sqrt(Func):
6670class Sqrt(Func):
6671    pass
key = 'sqrt'
class Stddev(AggFunc):
6674class Stddev(AggFunc):
6675    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6678class StddevPop(AggFunc):
6679    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6682class StddevSamp(AggFunc):
6683    pass
key = 'stddevsamp'
class Time(Func):
6687class Time(Func):
6688    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6691class TimeToStr(Func):
6692    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):
6695class TimeToTimeStr(Func):
6696    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6699class TimeToUnix(Func):
6700    pass
key = 'timetounix'
class TimeStrToDate(Func):
6703class TimeStrToDate(Func):
6704    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6707class TimeStrToTime(Func):
6708    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6711class TimeStrToUnix(Func):
6712    pass
key = 'timestrtounix'
class Trim(Func):
6715class Trim(Func):
6716    arg_types = {
6717        "this": True,
6718        "expression": False,
6719        "position": False,
6720        "collation": False,
6721    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6724class TsOrDsAdd(Func, TimeUnit):
6725    # return_type is used to correctly cast the arguments of this expression when transpiling it
6726    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6727
6728    @property
6729    def return_type(self) -> DataType:
6730        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
6728    @property
6729    def return_type(self) -> DataType:
6730        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6733class TsOrDsDiff(Func, TimeUnit):
6734    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6737class TsOrDsToDateStr(Func):
6738    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6741class TsOrDsToDate(Func):
6742    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6745class TsOrDsToDatetime(Func):
6746    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6749class TsOrDsToTime(Func):
6750    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6753class TsOrDsToTimestamp(Func):
6754    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6757class TsOrDiToDi(Func):
6758    pass
key = 'tsorditodi'
class Unhex(Func):
6761class Unhex(Func):
6762    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6765class Unicode(Func):
6766    pass
key = 'unicode'
class UnixDate(Func):
6770class UnixDate(Func):
6771    pass
key = 'unixdate'
class UnixToStr(Func):
6774class UnixToStr(Func):
6775    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6780class UnixToTime(Func):
6781    arg_types = {
6782        "this": True,
6783        "scale": False,
6784        "zone": False,
6785        "hours": False,
6786        "minutes": False,
6787        "format": False,
6788    }
6789
6790    SECONDS = Literal.number(0)
6791    DECIS = Literal.number(1)
6792    CENTIS = Literal.number(2)
6793    MILLIS = Literal.number(3)
6794    DECIMILLIS = Literal.number(4)
6795    CENTIMILLIS = Literal.number(5)
6796    MICROS = Literal.number(6)
6797    DECIMICROS = Literal.number(7)
6798    CENTIMICROS = Literal.number(8)
6799    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):
6802class UnixToTimeStr(Func):
6803    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6806class UnixSeconds(Func):
6807    pass
key = 'unixseconds'
class Uuid(Func):
6810class Uuid(Func):
6811    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6812
6813    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6816class TimestampFromParts(Func):
6817    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6818    arg_types = {
6819        "year": True,
6820        "month": True,
6821        "day": True,
6822        "hour": True,
6823        "min": True,
6824        "sec": True,
6825        "nano": False,
6826        "zone": False,
6827        "milli": False,
6828    }
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):
6831class Upper(Func):
6832    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6835class Corr(Binary, AggFunc):
6836    pass
key = 'corr'
class Variance(AggFunc):
6839class Variance(AggFunc):
6840    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6843class VariancePop(AggFunc):
6844    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6847class CovarSamp(Binary, AggFunc):
6848    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6851class CovarPop(Binary, AggFunc):
6852    pass
key = 'covarpop'
class Week(Func):
6855class Week(Func):
6856    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6859class XMLElement(Func):
6860    _sql_names = ["XMLELEMENT"]
6861    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6864class XMLTable(Func):
6865    arg_types = {
6866        "this": True,
6867        "namespaces": False,
6868        "passing": False,
6869        "columns": False,
6870        "by_ref": False,
6871    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6874class XMLNamespace(Expression):
6875    pass
key = 'xmlnamespace'
class Year(Func):
6878class Year(Func):
6879    pass
key = 'year'
class Use(Expression):
6882class Use(Expression):
6883    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6886class Merge(DML):
6887    arg_types = {
6888        "this": True,
6889        "using": True,
6890        "on": True,
6891        "whens": True,
6892        "with": False,
6893        "returning": False,
6894    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6897class When(Expression):
6898    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):
6901class Whens(Expression):
6902    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6903
6904    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6909class NextValueFor(Func):
6910    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6915class Semicolon(Expression):
6916    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:
6956def maybe_parse(
6957    sql_or_expression: ExpOrStr,
6958    *,
6959    into: t.Optional[IntoType] = None,
6960    dialect: DialectType = None,
6961    prefix: t.Optional[str] = None,
6962    copy: bool = False,
6963    **opts,
6964) -> Expression:
6965    """Gracefully handle a possible string or expression.
6966
6967    Example:
6968        >>> maybe_parse("1")
6969        Literal(this=1, is_string=False)
6970        >>> maybe_parse(to_identifier("x"))
6971        Identifier(this=x, quoted=False)
6972
6973    Args:
6974        sql_or_expression: the SQL code string or an expression
6975        into: the SQLGlot Expression to parse into
6976        dialect: the dialect used to parse the input expressions (in the case that an
6977            input expression is a SQL string).
6978        prefix: a string to prefix the sql with before it gets parsed
6979            (automatically includes a space)
6980        copy: whether to copy the expression.
6981        **opts: other options to use to parse the input expressions (again, in the case
6982            that an input expression is a SQL string).
6983
6984    Returns:
6985        Expression: the parsed or given expression.
6986    """
6987    if isinstance(sql_or_expression, Expression):
6988        if copy:
6989            return sql_or_expression.copy()
6990        return sql_or_expression
6991
6992    if sql_or_expression is None:
6993        raise ParseError("SQL cannot be None")
6994
6995    import sqlglot
6996
6997    sql = str(sql_or_expression)
6998    if prefix:
6999        sql = f"{prefix} {sql}"
7000
7001    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):
7012def maybe_copy(instance, copy=True):
7013    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:
7261def union(
7262    *expressions: ExpOrStr,
7263    distinct: bool = True,
7264    dialect: DialectType = None,
7265    copy: bool = True,
7266    **opts,
7267) -> Union:
7268    """
7269    Initializes a syntax tree for the `UNION` operation.
7270
7271    Example:
7272        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7273        'SELECT * FROM foo UNION SELECT * FROM bla'
7274
7275    Args:
7276        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7277            If `Expression` instances are passed, they will be used as-is.
7278        distinct: set the DISTINCT flag if and only if this is true.
7279        dialect: the dialect used to parse the input expression.
7280        copy: whether to copy the expression.
7281        opts: other options to use to parse the input expressions.
7282
7283    Returns:
7284        The new Union instance.
7285    """
7286    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7287    return _apply_set_operation(
7288        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7289    )

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:
7292def intersect(
7293    *expressions: ExpOrStr,
7294    distinct: bool = True,
7295    dialect: DialectType = None,
7296    copy: bool = True,
7297    **opts,
7298) -> Intersect:
7299    """
7300    Initializes a syntax tree for the `INTERSECT` operation.
7301
7302    Example:
7303        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7304        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7305
7306    Args:
7307        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7308            If `Expression` instances are passed, they will be used as-is.
7309        distinct: set the DISTINCT flag if and only if this is true.
7310        dialect: the dialect used to parse the input expression.
7311        copy: whether to copy the expression.
7312        opts: other options to use to parse the input expressions.
7313
7314    Returns:
7315        The new Intersect instance.
7316    """
7317    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7318    return _apply_set_operation(
7319        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7320    )

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

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

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:
7622def and_(
7623    *expressions: t.Optional[ExpOrStr],
7624    dialect: DialectType = None,
7625    copy: bool = True,
7626    wrap: bool = True,
7627    **opts,
7628) -> Condition:
7629    """
7630    Combine multiple conditions with an AND logical operator.
7631
7632    Example:
7633        >>> and_("x=1", and_("y=1", "z=1")).sql()
7634        'x = 1 AND (y = 1 AND z = 1)'
7635
7636    Args:
7637        *expressions: the SQL code strings to parse.
7638            If an Expression instance is passed, this is used as-is.
7639        dialect: the dialect used to parse the input expression.
7640        copy: whether to copy `expressions` (only applies to Expressions).
7641        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7642            precedence issues, but can be turned off when the produced AST is too deep and
7643            causes recursion-related issues.
7644        **opts: other options to use to parse the input expressions.
7645
7646    Returns:
7647        The new condition
7648    """
7649    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:
7652def or_(
7653    *expressions: t.Optional[ExpOrStr],
7654    dialect: DialectType = None,
7655    copy: bool = True,
7656    wrap: bool = True,
7657    **opts,
7658) -> Condition:
7659    """
7660    Combine multiple conditions with an OR logical operator.
7661
7662    Example:
7663        >>> or_("x=1", or_("y=1", "z=1")).sql()
7664        'x = 1 OR (y = 1 OR z = 1)'
7665
7666    Args:
7667        *expressions: the SQL code strings to parse.
7668            If an Expression instance is passed, this is used as-is.
7669        dialect: the dialect used to parse the input expression.
7670        copy: whether to copy `expressions` (only applies to Expressions).
7671        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7672            precedence issues, but can be turned off when the produced AST is too deep and
7673            causes recursion-related issues.
7674        **opts: other options to use to parse the input expressions.
7675
7676    Returns:
7677        The new condition
7678    """
7679    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:
7682def xor(
7683    *expressions: t.Optional[ExpOrStr],
7684    dialect: DialectType = None,
7685    copy: bool = True,
7686    wrap: bool = True,
7687    **opts,
7688) -> Condition:
7689    """
7690    Combine multiple conditions with an XOR logical operator.
7691
7692    Example:
7693        >>> xor("x=1", xor("y=1", "z=1")).sql()
7694        'x = 1 XOR (y = 1 XOR z = 1)'
7695
7696    Args:
7697        *expressions: the SQL code strings to parse.
7698            If an Expression instance is passed, this is used as-is.
7699        dialect: the dialect used to parse the input expression.
7700        copy: whether to copy `expressions` (only applies to Expressions).
7701        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7702            precedence issues, but can be turned off when the produced AST is too deep and
7703            causes recursion-related issues.
7704        **opts: other options to use to parse the input expressions.
7705
7706    Returns:
7707        The new condition
7708    """
7709    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:
7712def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7713    """
7714    Wrap a condition with a NOT operator.
7715
7716    Example:
7717        >>> not_("this_suit='black'").sql()
7718        "NOT this_suit = 'black'"
7719
7720    Args:
7721        expression: the SQL code string to parse.
7722            If an Expression instance is passed, this is used as-is.
7723        dialect: the dialect used to parse the input expression.
7724        copy: whether to copy the expression or not.
7725        **opts: other options to use to parse the input expressions.
7726
7727    Returns:
7728        The new condition.
7729    """
7730    this = condition(
7731        expression,
7732        dialect=dialect,
7733        copy=copy,
7734        **opts,
7735    )
7736    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:
7739def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7740    """
7741    Wrap an expression in parentheses.
7742
7743    Example:
7744        >>> paren("5 + 3").sql()
7745        '(5 + 3)'
7746
7747    Args:
7748        expression: the SQL code string to parse.
7749            If an Expression instance is passed, this is used as-is.
7750        copy: whether to copy the expression or not.
7751
7752    Returns:
7753        The wrapped expression.
7754    """
7755    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):
7771def to_identifier(name, quoted=None, copy=True):
7772    """Builds an identifier.
7773
7774    Args:
7775        name: The name to turn into an identifier.
7776        quoted: Whether to force quote the identifier.
7777        copy: Whether to copy name if it's an Identifier.
7778
7779    Returns:
7780        The identifier ast node.
7781    """
7782
7783    if name is None:
7784        return None
7785
7786    if isinstance(name, Identifier):
7787        identifier = maybe_copy(name, copy)
7788    elif isinstance(name, str):
7789        identifier = Identifier(
7790            this=name,
7791            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7792        )
7793    else:
7794        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7795    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:
7798def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7799    """
7800    Parses a given string into an identifier.
7801
7802    Args:
7803        name: The name to parse into an identifier.
7804        dialect: The dialect to parse against.
7805
7806    Returns:
7807        The identifier ast node.
7808    """
7809    try:
7810        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7811    except (ParseError, TokenError):
7812        expression = to_identifier(name)
7813
7814    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:
7820def to_interval(interval: str | Literal) -> Interval:
7821    """Builds an interval expression from a string like '1 day' or '5 months'."""
7822    if isinstance(interval, Literal):
7823        if not interval.is_string:
7824            raise ValueError("Invalid interval string.")
7825
7826        interval = interval.this
7827
7828    interval = maybe_parse(f"INTERVAL {interval}")
7829    assert isinstance(interval, Interval)
7830    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:
7833def to_table(
7834    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7835) -> Table:
7836    """
7837    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7838    If a table is passed in then that table is returned.
7839
7840    Args:
7841        sql_path: a `[catalog].[schema].[table]` string.
7842        dialect: the source dialect according to which the table name will be parsed.
7843        copy: Whether to copy a table if it is passed in.
7844        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7845
7846    Returns:
7847        A table expression.
7848    """
7849    if isinstance(sql_path, Table):
7850        return maybe_copy(sql_path, copy=copy)
7851
7852    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7853
7854    for k, v in kwargs.items():
7855        table.set(k, v)
7856
7857    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:
7860def to_column(
7861    sql_path: str | Column,
7862    quoted: t.Optional[bool] = None,
7863    dialect: DialectType = None,
7864    copy: bool = True,
7865    **kwargs,
7866) -> Column:
7867    """
7868    Create a column from a `[table].[column]` sql path. Table is optional.
7869    If a column is passed in then that column is returned.
7870
7871    Args:
7872        sql_path: a `[table].[column]` string.
7873        quoted: Whether or not to force quote identifiers.
7874        dialect: the source dialect according to which the column name will be parsed.
7875        copy: Whether to copy a column if it is passed in.
7876        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7877
7878    Returns:
7879        A column expression.
7880    """
7881    if isinstance(sql_path, Column):
7882        return maybe_copy(sql_path, copy=copy)
7883
7884    try:
7885        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7886    except ParseError:
7887        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7888
7889    for k, v in kwargs.items():
7890        col.set(k, v)
7891
7892    if quoted:
7893        for i in col.find_all(Identifier):
7894            i.set("quoted", True)
7895
7896    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):
7899def alias_(
7900    expression: ExpOrStr,
7901    alias: t.Optional[str | Identifier],
7902    table: bool | t.Sequence[str | Identifier] = False,
7903    quoted: t.Optional[bool] = None,
7904    dialect: DialectType = None,
7905    copy: bool = True,
7906    **opts,
7907):
7908    """Create an Alias expression.
7909
7910    Example:
7911        >>> alias_('foo', 'bar').sql()
7912        'foo AS bar'
7913
7914        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7915        '(SELECT 1, 2) AS bar(a, b)'
7916
7917    Args:
7918        expression: the SQL code strings to parse.
7919            If an Expression instance is passed, this is used as-is.
7920        alias: the alias name to use. If the name has
7921            special characters it is quoted.
7922        table: Whether to create a table alias, can also be a list of columns.
7923        quoted: whether to quote the alias
7924        dialect: the dialect used to parse the input expression.
7925        copy: Whether to copy the expression.
7926        **opts: other options to use to parse the input expressions.
7927
7928    Returns:
7929        Alias: the aliased expression
7930    """
7931    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7932    alias = to_identifier(alias, quoted=quoted)
7933
7934    if table:
7935        table_alias = TableAlias(this=alias)
7936        exp.set("alias", table_alias)
7937
7938        if not isinstance(table, bool):
7939            for column in table:
7940                table_alias.append("columns", to_identifier(column, quoted=quoted))
7941
7942        return exp
7943
7944    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7945    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7946    # for the complete Window expression.
7947    #
7948    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7949
7950    if "alias" in exp.arg_types and not isinstance(exp, Window):
7951        exp.set("alias", alias)
7952        return exp
7953    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:
7956def subquery(
7957    expression: ExpOrStr,
7958    alias: t.Optional[Identifier | str] = None,
7959    dialect: DialectType = None,
7960    **opts,
7961) -> Select:
7962    """
7963    Build a subquery expression that's selected from.
7964
7965    Example:
7966        >>> subquery('select x from tbl', 'bar').select('x').sql()
7967        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7968
7969    Args:
7970        expression: the SQL code strings to parse.
7971            If an Expression instance is passed, this is used as-is.
7972        alias: the alias name to use.
7973        dialect: the dialect used to parse the input expression.
7974        **opts: other options to use to parse the input expressions.
7975
7976    Returns:
7977        A new Select instance with the subquery expression included.
7978    """
7979
7980    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7981    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):
8012def column(
8013    col,
8014    table=None,
8015    db=None,
8016    catalog=None,
8017    *,
8018    fields=None,
8019    quoted=None,
8020    copy=True,
8021):
8022    """
8023    Build a Column.
8024
8025    Args:
8026        col: Column name.
8027        table: Table name.
8028        db: Database name.
8029        catalog: Catalog name.
8030        fields: Additional fields using dots.
8031        quoted: Whether to force quotes on the column's identifiers.
8032        copy: Whether to copy identifiers if passed in.
8033
8034    Returns:
8035        The new Column instance.
8036    """
8037    this = Column(
8038        this=to_identifier(col, quoted=quoted, copy=copy),
8039        table=to_identifier(table, quoted=quoted, copy=copy),
8040        db=to_identifier(db, quoted=quoted, copy=copy),
8041        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8042    )
8043
8044    if fields:
8045        this = Dot.build(
8046            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8047        )
8048    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:
8051def cast(
8052    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8053) -> Cast:
8054    """Cast an expression to a data type.
8055
8056    Example:
8057        >>> cast('x + 1', 'int').sql()
8058        'CAST(x + 1 AS INT)'
8059
8060    Args:
8061        expression: The expression to cast.
8062        to: The datatype to cast to.
8063        copy: Whether to copy the supplied expressions.
8064        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8065            - The expression to be cast is already a exp.Cast expression
8066            - The existing cast is to a type that is logically equivalent to new type
8067
8068            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8069            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8070            and instead just return the original expression `CAST(x as DATETIME)`.
8071
8072            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8073            mapping is applied in the target dialect generator.
8074
8075    Returns:
8076        The new Cast instance.
8077    """
8078    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8079    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8080
8081    # dont re-cast if the expression is already a cast to the correct type
8082    if isinstance(expr, Cast):
8083        from sqlglot.dialects.dialect import Dialect
8084
8085        target_dialect = Dialect.get_or_raise(dialect)
8086        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8087
8088        existing_cast_type: DataType.Type = expr.to.this
8089        new_cast_type: DataType.Type = data_type.this
8090        types_are_equivalent = type_mapping.get(
8091            existing_cast_type, existing_cast_type.value
8092        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8093
8094        if expr.is_type(data_type) or types_are_equivalent:
8095            return expr
8096
8097    expr = Cast(this=expr, to=data_type)
8098    expr.type = data_type
8099
8100    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:
8103def table_(
8104    table: Identifier | str,
8105    db: t.Optional[Identifier | str] = None,
8106    catalog: t.Optional[Identifier | str] = None,
8107    quoted: t.Optional[bool] = None,
8108    alias: t.Optional[Identifier | str] = None,
8109) -> Table:
8110    """Build a Table.
8111
8112    Args:
8113        table: Table name.
8114        db: Database name.
8115        catalog: Catalog name.
8116        quote: Whether to force quotes on the table's identifiers.
8117        alias: Table's alias.
8118
8119    Returns:
8120        The new Table instance.
8121    """
8122    return Table(
8123        this=to_identifier(table, quoted=quoted) if table else None,
8124        db=to_identifier(db, quoted=quoted) if db else None,
8125        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8126        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8127    )

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:
8130def values(
8131    values: t.Iterable[t.Tuple[t.Any, ...]],
8132    alias: t.Optional[str] = None,
8133    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8134) -> Values:
8135    """Build VALUES statement.
8136
8137    Example:
8138        >>> values([(1, '2')]).sql()
8139        "VALUES (1, '2')"
8140
8141    Args:
8142        values: values statements that will be converted to SQL
8143        alias: optional alias
8144        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8145         If either are provided then an alias is also required.
8146
8147    Returns:
8148        Values: the Values expression object
8149    """
8150    if columns and not alias:
8151        raise ValueError("Alias is required when providing columns")
8152
8153    return Values(
8154        expressions=[convert(tup) for tup in values],
8155        alias=(
8156            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8157            if columns
8158            else (TableAlias(this=to_identifier(alias)) if alias else None)
8159        ),
8160    )

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:
8163def var(name: t.Optional[ExpOrStr]) -> Var:
8164    """Build a SQL variable.
8165
8166    Example:
8167        >>> repr(var('x'))
8168        'Var(this=x)'
8169
8170        >>> repr(var(column('x', table='y')))
8171        'Var(this=x)'
8172
8173    Args:
8174        name: The name of the var or an expression who's name will become the var.
8175
8176    Returns:
8177        The new variable node.
8178    """
8179    if not name:
8180        raise ValueError("Cannot convert empty name into var.")
8181
8182    if isinstance(name, Expression):
8183        name = name.name
8184    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:
8187def rename_table(
8188    old_name: str | Table,
8189    new_name: str | Table,
8190    dialect: DialectType = None,
8191) -> Alter:
8192    """Build ALTER TABLE... RENAME... expression
8193
8194    Args:
8195        old_name: The old name of the table
8196        new_name: The new name of the table
8197        dialect: The dialect to parse the table.
8198
8199    Returns:
8200        Alter table expression
8201    """
8202    old_table = to_table(old_name, dialect=dialect)
8203    new_table = to_table(new_name, dialect=dialect)
8204    return Alter(
8205        this=old_table,
8206        kind="TABLE",
8207        actions=[
8208            AlterRename(this=new_table),
8209        ],
8210    )

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:
8213def rename_column(
8214    table_name: str | Table,
8215    old_column_name: str | Column,
8216    new_column_name: str | Column,
8217    exists: t.Optional[bool] = None,
8218    dialect: DialectType = None,
8219) -> Alter:
8220    """Build ALTER TABLE... RENAME COLUMN... expression
8221
8222    Args:
8223        table_name: Name of the table
8224        old_column: The old name of the column
8225        new_column: The new name of the column
8226        exists: Whether to add the `IF EXISTS` clause
8227        dialect: The dialect to parse the table/column.
8228
8229    Returns:
8230        Alter table expression
8231    """
8232    table = to_table(table_name, dialect=dialect)
8233    old_column = to_column(old_column_name, dialect=dialect)
8234    new_column = to_column(new_column_name, dialect=dialect)
8235    return Alter(
8236        this=table,
8237        kind="TABLE",
8238        actions=[
8239            RenameColumn(this=old_column, to=new_column, exists=exists),
8240        ],
8241    )

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:
8244def convert(value: t.Any, copy: bool = False) -> Expression:
8245    """Convert a python value into an expression object.
8246
8247    Raises an error if a conversion is not possible.
8248
8249    Args:
8250        value: A python object.
8251        copy: Whether to copy `value` (only applies to Expressions and collections).
8252
8253    Returns:
8254        The equivalent expression object.
8255    """
8256    if isinstance(value, Expression):
8257        return maybe_copy(value, copy)
8258    if isinstance(value, str):
8259        return Literal.string(value)
8260    if isinstance(value, bool):
8261        return Boolean(this=value)
8262    if value is None or (isinstance(value, float) and math.isnan(value)):
8263        return null()
8264    if isinstance(value, numbers.Number):
8265        return Literal.number(value)
8266    if isinstance(value, bytes):
8267        return HexString(this=value.hex())
8268    if isinstance(value, datetime.datetime):
8269        datetime_literal = Literal.string(value.isoformat(sep=" "))
8270
8271        tz = None
8272        if value.tzinfo:
8273            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8274            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8275            tz = Literal.string(str(value.tzinfo))
8276
8277        return TimeStrToTime(this=datetime_literal, zone=tz)
8278    if isinstance(value, datetime.date):
8279        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8280        return DateStrToDate(this=date_literal)
8281    if isinstance(value, tuple):
8282        if hasattr(value, "_fields"):
8283            return Struct(
8284                expressions=[
8285                    PropertyEQ(
8286                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8287                    )
8288                    for k in value._fields
8289                ]
8290            )
8291        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8292    if isinstance(value, list):
8293        return Array(expressions=[convert(v, copy=copy) for v in value])
8294    if isinstance(value, dict):
8295        return Map(
8296            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8297            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8298        )
8299    if hasattr(value, "__dict__"):
8300        return Struct(
8301            expressions=[
8302                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8303                for k, v in value.__dict__.items()
8304            ]
8305        )
8306    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:
8309def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8310    """
8311    Replace children of an expression with the result of a lambda fun(child) -> exp.
8312    """
8313    for k, v in tuple(expression.args.items()):
8314        is_list_arg = type(v) is list
8315
8316        child_nodes = v if is_list_arg else [v]
8317        new_child_nodes = []
8318
8319        for cn in child_nodes:
8320            if isinstance(cn, Expression):
8321                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8322                    new_child_nodes.append(child_node)
8323            else:
8324                new_child_nodes.append(cn)
8325
8326        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:
8329def replace_tree(
8330    expression: Expression,
8331    fun: t.Callable,
8332    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8333) -> Expression:
8334    """
8335    Replace an entire tree with the result of function calls on each node.
8336
8337    This will be traversed in reverse dfs, so leaves first.
8338    If new nodes are created as a result of function calls, they will also be traversed.
8339    """
8340    stack = list(expression.dfs(prune=prune))
8341
8342    while stack:
8343        node = stack.pop()
8344        new_node = fun(node)
8345
8346        if new_node is not node:
8347            node.replace(new_node)
8348
8349            if isinstance(new_node, Expression):
8350                stack.append(new_node)
8351
8352    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]:
8355def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8356    """
8357    Return all table names referenced through columns in an expression.
8358
8359    Example:
8360        >>> import sqlglot
8361        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8362        ['a', 'c']
8363
8364    Args:
8365        expression: expression to find table names.
8366        exclude: a table name to exclude
8367
8368    Returns:
8369        A list of unique names.
8370    """
8371    return {
8372        table
8373        for table in (column.table for column in expression.find_all(Column))
8374        if table and table != exclude
8375    }

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:
8378def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8379    """Get the full name of a table as a string.
8380
8381    Args:
8382        table: Table expression node or string.
8383        dialect: The dialect to generate the table name for.
8384        identify: Determines when an identifier should be quoted. Possible values are:
8385            False (default): Never quote, except in cases where it's mandatory by the dialect.
8386            True: Always quote.
8387
8388    Examples:
8389        >>> from sqlglot import exp, parse_one
8390        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8391        'a.b.c'
8392
8393    Returns:
8394        The table name.
8395    """
8396
8397    table = maybe_parse(table, into=Table, dialect=dialect)
8398
8399    if not table:
8400        raise ValueError(f"Cannot parse {table}")
8401
8402    return ".".join(
8403        (
8404            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8405            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8406            else part.name
8407        )
8408        for part in table.parts
8409    )

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:
8412def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8413    """Returns a case normalized table name without quotes.
8414
8415    Args:
8416        table: the table to normalize
8417        dialect: the dialect to use for normalization rules
8418        copy: whether to copy the expression.
8419
8420    Examples:
8421        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8422        'A-B.c'
8423    """
8424    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8425
8426    return ".".join(
8427        p.name
8428        for p in normalize_identifiers(
8429            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8430        ).parts
8431    )

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

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:
8667def tuple_(
8668    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8669) -> Tuple:
8670    """
8671    Returns an tuple.
8672
8673    Examples:
8674        >>> tuple_(1, 'x').sql()
8675        '(1, x)'
8676
8677    Args:
8678        expressions: the expressions to add to the tuple.
8679        copy: whether to copy the argument expressions.
8680        dialect: the source dialect.
8681        kwargs: the kwargs used to instantiate the function of interest.
8682
8683    Returns:
8684        A tuple expression.
8685    """
8686    return Tuple(
8687        expressions=[
8688            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8689            for expression in expressions
8690        ]
8691    )

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:
8694def true() -> Boolean:
8695    """
8696    Returns a true Boolean expression.
8697    """
8698    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8701def false() -> Boolean:
8702    """
8703    Returns a false Boolean expression.
8704    """
8705    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8708def null() -> Null:
8709    """
8710    Returns a Null expression.
8711    """
8712    return Null()

Returns a Null expression.

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