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

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

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

Returns the output names of the query's projections.

is_star: bool
3392    @property
3393    def is_star(self) -> bool:
3394        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3396    @property
3397    def selects(self) -> t.List[Expression]:
3398        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
4219    @property
4220    def selects(self) -> t.List[Expression]:
4221        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4306class Pivot(Expression):
4307    arg_types = {
4308        "this": False,
4309        "alias": False,
4310        "expressions": False,
4311        "field": False,
4312        "unpivot": False,
4313        "using": False,
4314        "group": False,
4315        "columns": False,
4316        "include_nulls": False,
4317        "default_on_null": False,
4318        "into": False,
4319    }
4320
4321    @property
4322    def unpivot(self) -> bool:
4323        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
4321    @property
4322    def unpivot(self) -> bool:
4323        return bool(self.args.get("unpivot"))
key = 'pivot'
class UnpivotColumns(Expression):
4328class UnpivotColumns(Expression):
4329    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4332class Window(Condition):
4333    arg_types = {
4334        "this": True,
4335        "partition_by": False,
4336        "order": False,
4337        "spec": False,
4338        "alias": False,
4339        "over": False,
4340        "first": False,
4341    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4344class WindowSpec(Expression):
4345    arg_types = {
4346        "kind": False,
4347        "start": False,
4348        "start_side": False,
4349        "end": False,
4350        "end_side": False,
4351    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4354class PreWhere(Expression):
4355    pass
key = 'prewhere'
class Where(Expression):
4358class Where(Expression):
4359    pass
key = 'where'
class Star(Expression):
4362class Star(Expression):
4363    arg_types = {"except": False, "replace": False, "rename": False}
4364
4365    @property
4366    def name(self) -> str:
4367        return "*"
4368
4369    @property
4370    def output_name(self) -> str:
4371        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4365    @property
4366    def name(self) -> str:
4367        return "*"
output_name: str
4369    @property
4370    def output_name(self) -> str:
4371        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):
4374class Parameter(Condition):
4375    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4378class SessionParameter(Condition):
4379    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4382class Placeholder(Condition):
4383    arg_types = {"this": False, "kind": False}
4384
4385    @property
4386    def name(self) -> str:
4387        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4385    @property
4386    def name(self) -> str:
4387        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4390class Null(Condition):
4391    arg_types: t.Dict[str, t.Any] = {}
4392
4393    @property
4394    def name(self) -> str:
4395        return "NULL"
4396
4397    def to_py(self) -> Lit[None]:
4398        return None
arg_types: Dict[str, Any] = {}
name: str
4393    @property
4394    def name(self) -> str:
4395        return "NULL"
def to_py(self) -> Literal[None]:
4397    def to_py(self) -> Lit[None]:
4398        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4401class Boolean(Condition):
4402    def to_py(self) -> bool:
4403        return self.this
def to_py(self) -> bool:
4402    def to_py(self) -> bool:
4403        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4955class DPipe(Binary):
4956    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4959class EQ(Binary, Predicate):
4960    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4963class NullSafeEQ(Binary, Predicate):
4964    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4967class NullSafeNEQ(Binary, Predicate):
4968    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4972class PropertyEQ(Binary):
4973    pass
key = 'propertyeq'
class Distance(Binary):
4976class Distance(Binary):
4977    pass
key = 'distance'
class Escape(Binary):
4980class Escape(Binary):
4981    pass
key = 'escape'
class Glob(Binary, Predicate):
4984class Glob(Binary, Predicate):
4985    pass
key = 'glob'
class GT(Binary, Predicate):
4988class GT(Binary, Predicate):
4989    pass
key = 'gt'
class GTE(Binary, Predicate):
4992class GTE(Binary, Predicate):
4993    pass
key = 'gte'
class ILike(Binary, Predicate):
4996class ILike(Binary, Predicate):
4997    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5000class ILikeAny(Binary, Predicate):
5001    pass
key = 'ilikeany'
class IntDiv(Binary):
5004class IntDiv(Binary):
5005    pass
key = 'intdiv'
class Is(Binary, Predicate):
5008class Is(Binary, Predicate):
5009    pass
key = 'is'
class Kwarg(Binary):
5012class Kwarg(Binary):
5013    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5016class Like(Binary, Predicate):
5017    pass
key = 'like'
class LikeAny(Binary, Predicate):
5020class LikeAny(Binary, Predicate):
5021    pass
key = 'likeany'
class LT(Binary, Predicate):
5024class LT(Binary, Predicate):
5025    pass
key = 'lt'
class LTE(Binary, Predicate):
5028class LTE(Binary, Predicate):
5029    pass
key = 'lte'
class Mod(Binary):
5032class Mod(Binary):
5033    pass
key = 'mod'
class Mul(Binary):
5036class Mul(Binary):
5037    pass
key = 'mul'
class NEQ(Binary, Predicate):
5040class NEQ(Binary, Predicate):
5041    pass
key = 'neq'
class Operator(Binary):
5045class Operator(Binary):
5046    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5049class SimilarTo(Binary, Predicate):
5050    pass
key = 'similarto'
class Slice(Binary):
5053class Slice(Binary):
5054    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5057class Sub(Binary):
5058    pass
key = 'sub'
class Unary(Condition):
5063class Unary(Condition):
5064    pass
key = 'unary'
class BitwiseNot(Unary):
5067class BitwiseNot(Unary):
5068    pass
key = 'bitwisenot'
class Not(Unary):
5071class Not(Unary):
5072    pass
key = 'not'
class Paren(Unary):
5075class Paren(Unary):
5076    @property
5077    def output_name(self) -> str:
5078        return self.this.name
output_name: str
5076    @property
5077    def output_name(self) -> str:
5078        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):
5081class Neg(Unary):
5082    def to_py(self) -> int | Decimal:
5083        if self.is_number:
5084            return self.this.to_py() * -1
5085        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5082    def to_py(self) -> int | Decimal:
5083        if self.is_number:
5084            return self.this.to_py() * -1
5085        return super().to_py()

Returns a Python object equivalent of the SQL node.

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

Automatically converts unit arg into a var.

TimeUnit(**args)
5191    def __init__(self, **args):
5192        unit = args.get("unit")
5193        if isinstance(unit, self.VAR_LIKE):
5194            args["unit"] = Var(
5195                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5196            )
5197        elif isinstance(unit, Week):
5198            unit.set("this", Var(this=unit.this.name.upper()))
5199
5200        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]
5202    @property
5203    def unit(self) -> t.Optional[Var | IntervalSpan]:
5204        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5207class IntervalOp(TimeUnit):
5208    arg_types = {"unit": False, "expression": True}
5209
5210    def interval(self):
5211        return Interval(
5212            this=self.expression.copy(),
5213            unit=self.unit.copy() if self.unit else None,
5214        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5210    def interval(self):
5211        return Interval(
5212            this=self.expression.copy(),
5213            unit=self.unit.copy() if self.unit else None,
5214        )
key = 'intervalop'
class IntervalSpan(DataType):
5220class IntervalSpan(DataType):
5221    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5224class Interval(TimeUnit):
5225    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5228class IgnoreNulls(Expression):
5229    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5232class RespectNulls(Expression):
5233    pass
key = 'respectnulls'
class HavingMax(Expression):
5237class HavingMax(Expression):
5238    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5242class Func(Condition):
5243    """
5244    The base class for all function expressions.
5245
5246    Attributes:
5247        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5248            treated as a variable length argument and the argument's value will be stored as a list.
5249        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5250            function expression. These values are used to map this node to a name during parsing as
5251            well as to provide the function's name during SQL string generation. By default the SQL
5252            name is set to the expression's class name transformed to snake case.
5253    """
5254
5255    is_var_len_args = False
5256
5257    @classmethod
5258    def from_arg_list(cls, args):
5259        if cls.is_var_len_args:
5260            all_arg_keys = list(cls.arg_types)
5261            # If this function supports variable length argument treat the last argument as such.
5262            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5263            num_non_var = len(non_var_len_arg_keys)
5264
5265            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5266            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5267        else:
5268            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5269
5270        return cls(**args_dict)
5271
5272    @classmethod
5273    def sql_names(cls):
5274        if cls is Func:
5275            raise NotImplementedError(
5276                "SQL name is only supported by concrete function implementations"
5277            )
5278        if "_sql_names" not in cls.__dict__:
5279            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5280        return cls._sql_names
5281
5282    @classmethod
5283    def sql_name(cls):
5284        return cls.sql_names()[0]
5285
5286    @classmethod
5287    def default_parser_mappings(cls):
5288        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):
5257    @classmethod
5258    def from_arg_list(cls, args):
5259        if cls.is_var_len_args:
5260            all_arg_keys = list(cls.arg_types)
5261            # If this function supports variable length argument treat the last argument as such.
5262            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5263            num_non_var = len(non_var_len_arg_keys)
5264
5265            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5266            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5267        else:
5268            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5269
5270        return cls(**args_dict)
@classmethod
def sql_names(cls):
5272    @classmethod
5273    def sql_names(cls):
5274        if cls is Func:
5275            raise NotImplementedError(
5276                "SQL name is only supported by concrete function implementations"
5277            )
5278        if "_sql_names" not in cls.__dict__:
5279            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5280        return cls._sql_names
@classmethod
def sql_name(cls):
5282    @classmethod
5283    def sql_name(cls):
5284        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5286    @classmethod
5287    def default_parser_mappings(cls):
5288        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5291class AggFunc(Func):
5292    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5295class ParameterizedAgg(AggFunc):
5296    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5299class Abs(Func):
5300    pass
key = 'abs'
class ArgMax(AggFunc):
5303class ArgMax(AggFunc):
5304    arg_types = {"this": True, "expression": True, "count": False}
5305    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5308class ArgMin(AggFunc):
5309    arg_types = {"this": True, "expression": True, "count": False}
5310    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5313class ApproxTopK(AggFunc):
5314    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5317class Flatten(Func):
5318    pass
key = 'flatten'
class Transform(Func):
5322class Transform(Func):
5323    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5326class Anonymous(Func):
5327    arg_types = {"this": True, "expressions": False}
5328    is_var_len_args = True
5329
5330    @property
5331    def name(self) -> str:
5332        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
5330    @property
5331    def name(self) -> str:
5332        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5335class AnonymousAggFunc(AggFunc):
5336    arg_types = {"this": True, "expressions": False}
5337    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5341class CombinedAggFunc(AnonymousAggFunc):
5342    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5345class CombinedParameterizedAgg(ParameterizedAgg):
5346    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5351class Hll(AggFunc):
5352    arg_types = {"this": True, "expressions": False}
5353    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5356class ApproxDistinct(AggFunc):
5357    arg_types = {"this": True, "accuracy": False}
5358    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5361class Apply(Func):
5362    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5365class Array(Func):
5366    arg_types = {"expressions": False, "bracket_notation": False}
5367    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5371class ToArray(Func):
5372    pass
key = 'toarray'
class List(Func):
5376class List(Func):
5377    arg_types = {"expressions": False}
5378    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5382class Pad(Func):
5383    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):
5388class ToChar(Func):
5389    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5394class ToNumber(Func):
5395    arg_types = {
5396        "this": True,
5397        "format": False,
5398        "nlsparam": False,
5399        "precision": False,
5400        "scale": False,
5401    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5405class ToDouble(Func):
5406    arg_types = {
5407        "this": True,
5408        "format": False,
5409    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5412class Columns(Func):
5413    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5417class Convert(Func):
5418    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5421class ConvertTimezone(Func):
5422    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):
5425class GenerateSeries(Func):
5426    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):
5432class ExplodingGenerateSeries(GenerateSeries):
5433    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5436class ArrayAgg(AggFunc):
5437    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5440class ArrayUniqueAgg(AggFunc):
5441    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5444class ArrayAll(Func):
5445    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5449class ArrayAny(Func):
5450    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5453class ArrayConcat(Func):
5454    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5455    arg_types = {"this": True, "expressions": False}
5456    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5459class ArrayConstructCompact(Func):
5460    arg_types = {"expressions": True}
5461    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5464class ArrayContains(Binary, Func):
5465    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5468class ArrayContainsAll(Binary, Func):
5469    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5472class ArrayFilter(Func):
5473    arg_types = {"this": True, "expression": True}
5474    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5477class ArrayToString(Func):
5478    arg_types = {"this": True, "expression": True, "null": False}
5479    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5483class String(Func):
5484    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5487class StringToArray(Func):
5488    arg_types = {"this": True, "expression": True, "null": False}
5489    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5492class ArrayOverlaps(Binary, Func):
5493    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5496class ArraySize(Func):
5497    arg_types = {"this": True, "expression": False}
5498    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5501class ArraySort(Func):
5502    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5505class ArraySum(Func):
5506    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5509class ArrayUnionAgg(AggFunc):
5510    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5513class Avg(AggFunc):
5514    pass
key = 'avg'
class AnyValue(AggFunc):
5517class AnyValue(AggFunc):
5518    pass
key = 'anyvalue'
class Lag(AggFunc):
5521class Lag(AggFunc):
5522    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5525class Lead(AggFunc):
5526    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5531class First(AggFunc):
5532    pass
key = 'first'
class Last(AggFunc):
5535class Last(AggFunc):
5536    pass
key = 'last'
class FirstValue(AggFunc):
5539class FirstValue(AggFunc):
5540    pass
key = 'firstvalue'
class LastValue(AggFunc):
5543class LastValue(AggFunc):
5544    pass
key = 'lastvalue'
class NthValue(AggFunc):
5547class NthValue(AggFunc):
5548    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5551class Case(Func):
5552    arg_types = {"this": False, "ifs": True, "default": False}
5553
5554    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5555        instance = maybe_copy(self, copy)
5556        instance.append(
5557            "ifs",
5558            If(
5559                this=maybe_parse(condition, copy=copy, **opts),
5560                true=maybe_parse(then, copy=copy, **opts),
5561            ),
5562        )
5563        return instance
5564
5565    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5566        instance = maybe_copy(self, copy)
5567        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5568        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:
5554    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5555        instance = maybe_copy(self, copy)
5556        instance.append(
5557            "ifs",
5558            If(
5559                this=maybe_parse(condition, copy=copy, **opts),
5560                true=maybe_parse(then, copy=copy, **opts),
5561            ),
5562        )
5563        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5565    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5566        instance = maybe_copy(self, copy)
5567        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5568        return instance
key = 'case'
class Cast(Func):
5571class Cast(Func):
5572    arg_types = {
5573        "this": True,
5574        "to": True,
5575        "format": False,
5576        "safe": False,
5577        "action": False,
5578        "default": False,
5579    }
5580
5581    @property
5582    def name(self) -> str:
5583        return self.this.name
5584
5585    @property
5586    def to(self) -> DataType:
5587        return self.args["to"]
5588
5589    @property
5590    def output_name(self) -> str:
5591        return self.name
5592
5593    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5594        """
5595        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5596        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5597        array<int> != array<float>.
5598
5599        Args:
5600            dtypes: the data types to compare this Cast's DataType to.
5601
5602        Returns:
5603            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5604        """
5605        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5581    @property
5582    def name(self) -> str:
5583        return self.this.name
to: DataType
5585    @property
5586    def to(self) -> DataType:
5587        return self.args["to"]
output_name: str
5589    @property
5590    def output_name(self) -> str:
5591        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:
5593    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5594        """
5595        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5596        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5597        array<int> != array<float>.
5598
5599        Args:
5600            dtypes: the data types to compare this Cast's DataType to.
5601
5602        Returns:
5603            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5604        """
5605        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):
5608class TryCast(Cast):
5609    pass
key = 'trycast'
class JSONCast(Cast):
5613class JSONCast(Cast):
5614    pass
key = 'jsoncast'
class Try(Func):
5617class Try(Func):
5618    pass
key = 'try'
class CastToStrType(Func):
5621class CastToStrType(Func):
5622    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5625class Collate(Binary, Func):
5626    pass
key = 'collate'
class Ceil(Func):
5629class Ceil(Func):
5630    arg_types = {"this": True, "decimals": False, "to": False}
5631    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5634class Coalesce(Func):
5635    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5636    is_var_len_args = True
5637    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5640class Chr(Func):
5641    arg_types = {"expressions": True, "charset": False}
5642    is_var_len_args = True
5643    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5646class Concat(Func):
5647    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5648    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5651class ConcatWs(Concat):
5652    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5655class Contains(Func):
5656    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5660class ConnectByRoot(Func):
5661    pass
key = 'connectbyroot'
class Count(AggFunc):
5664class Count(AggFunc):
5665    arg_types = {"this": False, "expressions": False, "big_int": False}
5666    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5669class CountIf(AggFunc):
5670    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5674class Cbrt(Func):
5675    pass
key = 'cbrt'
class CurrentDate(Func):
5678class CurrentDate(Func):
5679    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5682class CurrentDatetime(Func):
5683    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5686class CurrentTime(Func):
5687    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5690class CurrentTimestamp(Func):
5691    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5694class CurrentSchema(Func):
5695    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5698class CurrentUser(Func):
5699    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5702class DateAdd(Func, IntervalOp):
5703    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5706class DateBin(Func, IntervalOp):
5707    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):
5710class DateSub(Func, IntervalOp):
5711    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5714class DateDiff(Func, TimeUnit):
5715    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5716    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5719class DateTrunc(Func):
5720    arg_types = {"unit": True, "this": True, "zone": False}
5721
5722    def __init__(self, **args):
5723        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5724        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5725        unabbreviate = args.pop("unabbreviate", True)
5726
5727        unit = args.get("unit")
5728        if isinstance(unit, TimeUnit.VAR_LIKE):
5729            unit_name = unit.name.upper()
5730            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5731                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5732
5733            args["unit"] = Literal.string(unit_name)
5734        elif isinstance(unit, Week):
5735            unit.set("this", Literal.string(unit.this.name.upper()))
5736
5737        super().__init__(**args)
5738
5739    @property
5740    def unit(self) -> Expression:
5741        return self.args["unit"]
DateTrunc(**args)
5722    def __init__(self, **args):
5723        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5724        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5725        unabbreviate = args.pop("unabbreviate", True)
5726
5727        unit = args.get("unit")
5728        if isinstance(unit, TimeUnit.VAR_LIKE):
5729            unit_name = unit.name.upper()
5730            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5731                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5732
5733            args["unit"] = Literal.string(unit_name)
5734        elif isinstance(unit, Week):
5735            unit.set("this", Literal.string(unit.this.name.upper()))
5736
5737        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5739    @property
5740    def unit(self) -> Expression:
5741        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5746class Datetime(Func):
5747    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5750class DatetimeAdd(Func, IntervalOp):
5751    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5754class DatetimeSub(Func, IntervalOp):
5755    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5758class DatetimeDiff(Func, TimeUnit):
5759    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5762class DatetimeTrunc(Func, TimeUnit):
5763    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5766class DayOfWeek(Func):
5767    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5772class DayOfWeekIso(Func):
5773    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5776class DayOfMonth(Func):
5777    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5780class DayOfYear(Func):
5781    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5784class ToDays(Func):
5785    pass
key = 'todays'
class WeekOfYear(Func):
5788class WeekOfYear(Func):
5789    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5792class MonthsBetween(Func):
5793    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5796class MakeInterval(Func):
5797    arg_types = {
5798        "year": False,
5799        "month": False,
5800        "day": False,
5801        "hour": False,
5802        "minute": False,
5803        "second": False,
5804    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5807class LastDay(Func, TimeUnit):
5808    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5809    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5812class Extract(Func):
5813    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5816class Exists(Func, SubqueryPredicate):
5817    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5820class Timestamp(Func):
5821    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5824class TimestampAdd(Func, TimeUnit):
5825    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5828class TimestampSub(Func, TimeUnit):
5829    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5832class TimestampDiff(Func, TimeUnit):
5833    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5834    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5837class TimestampTrunc(Func, TimeUnit):
5838    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5841class TimeAdd(Func, TimeUnit):
5842    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5845class TimeSub(Func, TimeUnit):
5846    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5849class TimeDiff(Func, TimeUnit):
5850    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5853class TimeTrunc(Func, TimeUnit):
5854    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5857class DateFromParts(Func):
5858    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5859    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5862class TimeFromParts(Func):
5863    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5864    arg_types = {
5865        "hour": True,
5866        "min": True,
5867        "sec": True,
5868        "nano": False,
5869        "fractions": False,
5870        "precision": False,
5871    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5874class DateStrToDate(Func):
5875    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5878class DateToDateStr(Func):
5879    pass
key = 'datetodatestr'
class DateToDi(Func):
5882class DateToDi(Func):
5883    pass
key = 'datetodi'
class Date(Func):
5887class Date(Func):
5888    arg_types = {"this": False, "zone": False, "expressions": False}
5889    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5892class Day(Func):
5893    pass
key = 'day'
class Decode(Func):
5896class Decode(Func):
5897    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5900class DiToDate(Func):
5901    pass
key = 'ditodate'
class Encode(Func):
5904class Encode(Func):
5905    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5908class Exp(Func):
5909    pass
key = 'exp'
class Explode(Func, UDTF):
5913class Explode(Func, UDTF):
5914    arg_types = {"this": True, "expressions": False}
5915    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5919class Inline(Func):
5920    pass
key = 'inline'
class ExplodeOuter(Explode):
5923class ExplodeOuter(Explode):
5924    pass
key = 'explodeouter'
class Posexplode(Explode):
5927class Posexplode(Explode):
5928    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5931class PosexplodeOuter(Posexplode, ExplodeOuter):
5932    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5935class Unnest(Func, UDTF):
5936    arg_types = {
5937        "expressions": True,
5938        "alias": False,
5939        "offset": False,
5940        "explode_array": False,
5941    }
5942
5943    @property
5944    def selects(self) -> t.List[Expression]:
5945        columns = super().selects
5946        offset = self.args.get("offset")
5947        if offset:
5948            columns = columns + [to_identifier("offset") if offset is True else offset]
5949        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5943    @property
5944    def selects(self) -> t.List[Expression]:
5945        columns = super().selects
5946        offset = self.args.get("offset")
5947        if offset:
5948            columns = columns + [to_identifier("offset") if offset is True else offset]
5949        return columns
key = 'unnest'
class Floor(Func):
5952class Floor(Func):
5953    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5956class FromBase64(Func):
5957    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5960class FeaturesAtTime(Func):
5961    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):
5964class ToBase64(Func):
5965    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5969class FromISO8601Timestamp(Func):
5970    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5973class GapFill(Func):
5974    arg_types = {
5975        "this": True,
5976        "ts_column": True,
5977        "bucket_width": True,
5978        "partitioning_columns": False,
5979        "value_columns": False,
5980        "origin": False,
5981        "ignore_nulls": False,
5982    }
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):
5986class GenerateDateArray(Func):
5987    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5991class GenerateTimestampArray(Func):
5992    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5995class Greatest(Func):
5996    arg_types = {"this": True, "expressions": False}
5997    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6002class OverflowTruncateBehavior(Expression):
6003    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6006class GroupConcat(AggFunc):
6007    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6010class Hex(Func):
6011    pass
key = 'hex'
class LowerHex(Hex):
6014class LowerHex(Hex):
6015    pass
key = 'lowerhex'
class And(Connector, Func):
6018class And(Connector, Func):
6019    pass
key = 'and'
class Or(Connector, Func):
6022class Or(Connector, Func):
6023    pass
key = 'or'
class Xor(Connector, Func):
6026class Xor(Connector, Func):
6027    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6030class If(Func):
6031    arg_types = {"this": True, "true": True, "false": False}
6032    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6035class Nullif(Func):
6036    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6039class Initcap(Func):
6040    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6043class IsAscii(Func):
6044    pass
key = 'isascii'
class IsNan(Func):
6047class IsNan(Func):
6048    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6052class Int64(Func):
6053    pass
key = 'int64'
class IsInf(Func):
6056class IsInf(Func):
6057    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6061class JSON(Expression):
6062    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6065class JSONPath(Expression):
6066    arg_types = {"expressions": True, "escape": False}
6067
6068    @property
6069    def output_name(self) -> str:
6070        last_segment = self.expressions[-1].this
6071        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6068    @property
6069    def output_name(self) -> str:
6070        last_segment = self.expressions[-1].this
6071        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):
6074class JSONPathPart(Expression):
6075    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6078class JSONPathFilter(JSONPathPart):
6079    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6082class JSONPathKey(JSONPathPart):
6083    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6086class JSONPathRecursive(JSONPathPart):
6087    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6090class JSONPathRoot(JSONPathPart):
6091    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6094class JSONPathScript(JSONPathPart):
6095    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6098class JSONPathSlice(JSONPathPart):
6099    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6102class JSONPathSelector(JSONPathPart):
6103    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6106class JSONPathSubscript(JSONPathPart):
6107    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6110class JSONPathUnion(JSONPathPart):
6111    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6114class JSONPathWildcard(JSONPathPart):
6115    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6118class FormatJson(Expression):
6119    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6122class JSONKeyValue(Expression):
6123    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6126class JSONObject(Func):
6127    arg_types = {
6128        "expressions": False,
6129        "null_handling": False,
6130        "unique_keys": False,
6131        "return_type": False,
6132        "encoding": False,
6133    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6136class JSONObjectAgg(AggFunc):
6137    arg_types = {
6138        "expressions": False,
6139        "null_handling": False,
6140        "unique_keys": False,
6141        "return_type": False,
6142        "encoding": False,
6143    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6147class JSONBObjectAgg(AggFunc):
6148    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6152class JSONArray(Func):
6153    arg_types = {
6154        "expressions": True,
6155        "null_handling": False,
6156        "return_type": False,
6157        "strict": False,
6158    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6162class JSONArrayAgg(Func):
6163    arg_types = {
6164        "this": True,
6165        "order": False,
6166        "null_handling": False,
6167        "return_type": False,
6168        "strict": False,
6169    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6172class JSONExists(Func):
6173    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):
6178class JSONColumnDef(Expression):
6179    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):
6182class JSONSchema(Expression):
6183    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6187class JSONValue(Expression):
6188    arg_types = {
6189        "this": True,
6190        "path": True,
6191        "returning": False,
6192        "on_condition": False,
6193    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6196class JSONValueArray(Func):
6197    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6201class JSONTable(Func):
6202    arg_types = {
6203        "this": True,
6204        "schema": True,
6205        "path": False,
6206        "error_handling": False,
6207        "empty_handling": False,
6208    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6212class ObjectInsert(Func):
6213    arg_types = {
6214        "this": True,
6215        "key": True,
6216        "value": True,
6217        "update_flag": False,
6218    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6221class OpenJSONColumnDef(Expression):
6222    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):
6225class OpenJSON(Func):
6226    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6229class JSONBContains(Binary, Func):
6230    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6233class JSONBExists(Func):
6234    arg_types = {"this": True, "path": True}
6235    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6238class JSONExtract(Binary, Func):
6239    arg_types = {
6240        "this": True,
6241        "expression": True,
6242        "only_json_types": False,
6243        "expressions": False,
6244        "variant_extract": False,
6245        "json_query": False,
6246        "option": False,
6247        "quote": False,
6248        "on_condition": False,
6249    }
6250    _sql_names = ["JSON_EXTRACT"]
6251    is_var_len_args = True
6252
6253    @property
6254    def output_name(self) -> str:
6255        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
6253    @property
6254    def output_name(self) -> str:
6255        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):
6259class JSONExtractQuote(Expression):
6260    arg_types = {
6261        "option": True,
6262        "scalar": False,
6263    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6266class JSONExtractArray(Func):
6267    arg_types = {"this": True, "expression": False}
6268    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6271class JSONExtractScalar(Binary, Func):
6272    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6273    _sql_names = ["JSON_EXTRACT_SCALAR"]
6274    is_var_len_args = True
6275
6276    @property
6277    def output_name(self) -> str:
6278        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
6276    @property
6277    def output_name(self) -> str:
6278        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):
6281class JSONBExtract(Binary, Func):
6282    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6285class JSONBExtractScalar(Binary, Func):
6286    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6289class JSONFormat(Func):
6290    arg_types = {"this": False, "options": False}
6291    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6295class JSONArrayContains(Binary, Predicate, Func):
6296    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6299class ParseJSON(Func):
6300    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6301    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6302    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6303    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6306class Least(Func):
6307    arg_types = {"this": True, "expressions": False}
6308    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6311class Left(Func):
6312    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6319class Length(Func):
6320    arg_types = {"this": True, "binary": False, "encoding": False}
6321    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6324class Levenshtein(Func):
6325    arg_types = {
6326        "this": True,
6327        "expression": False,
6328        "ins_cost": False,
6329        "del_cost": False,
6330        "sub_cost": False,
6331        "max_dist": False,
6332    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6335class Ln(Func):
6336    pass
key = 'ln'
class Log(Func):
6339class Log(Func):
6340    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6343class LogicalOr(AggFunc):
6344    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6347class LogicalAnd(AggFunc):
6348    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6351class Lower(Func):
6352    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6355class Map(Func):
6356    arg_types = {"keys": False, "values": False}
6357
6358    @property
6359    def keys(self) -> t.List[Expression]:
6360        keys = self.args.get("keys")
6361        return keys.expressions if keys else []
6362
6363    @property
6364    def values(self) -> t.List[Expression]:
6365        values = self.args.get("values")
6366        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6358    @property
6359    def keys(self) -> t.List[Expression]:
6360        keys = self.args.get("keys")
6361        return keys.expressions if keys else []
values: List[Expression]
6363    @property
6364    def values(self) -> t.List[Expression]:
6365        values = self.args.get("values")
6366        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6370class ToMap(Func):
6371    pass
key = 'tomap'
class MapFromEntries(Func):
6374class MapFromEntries(Func):
6375    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6379class ScopeResolution(Expression):
6380    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6383class Stream(Expression):
6384    pass
key = 'stream'
class StarMap(Func):
6387class StarMap(Func):
6388    pass
key = 'starmap'
class VarMap(Func):
6391class VarMap(Func):
6392    arg_types = {"keys": True, "values": True}
6393    is_var_len_args = True
6394
6395    @property
6396    def keys(self) -> t.List[Expression]:
6397        return self.args["keys"].expressions
6398
6399    @property
6400    def values(self) -> t.List[Expression]:
6401        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6395    @property
6396    def keys(self) -> t.List[Expression]:
6397        return self.args["keys"].expressions
values: List[Expression]
6399    @property
6400    def values(self) -> t.List[Expression]:
6401        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6405class MatchAgainst(Func):
6406    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6409class Max(AggFunc):
6410    arg_types = {"this": True, "expressions": False}
6411    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6414class MD5(Func):
6415    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6419class MD5Digest(Func):
6420    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6423class Median(AggFunc):
6424    pass
key = 'median'
class Min(AggFunc):
6427class Min(AggFunc):
6428    arg_types = {"this": True, "expressions": False}
6429    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6432class Month(Func):
6433    pass
key = 'month'
class AddMonths(Func):
6436class AddMonths(Func):
6437    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6440class Nvl2(Func):
6441    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6444class Normalize(Func):
6445    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6448class Overlay(Func):
6449    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):
6453class Predict(Func):
6454    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6457class Pow(Binary, Func):
6458    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6461class PercentileCont(AggFunc):
6462    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6465class PercentileDisc(AggFunc):
6466    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6469class Quantile(AggFunc):
6470    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6473class ApproxQuantile(Quantile):
6474    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):
6477class Quarter(Func):
6478    pass
key = 'quarter'
class Rand(Func):
6483class Rand(Func):
6484    _sql_names = ["RAND", "RANDOM"]
6485    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6488class Randn(Func):
6489    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6492class RangeN(Func):
6493    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6496class ReadCSV(Func):
6497    _sql_names = ["READ_CSV"]
6498    is_var_len_args = True
6499    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6502class Reduce(Func):
6503    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):
6506class RegexpExtract(Func):
6507    arg_types = {
6508        "this": True,
6509        "expression": True,
6510        "position": False,
6511        "occurrence": False,
6512        "parameters": False,
6513        "group": False,
6514    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6517class RegexpExtractAll(Func):
6518    arg_types = {
6519        "this": True,
6520        "expression": True,
6521        "position": False,
6522        "occurrence": False,
6523        "parameters": False,
6524        "group": False,
6525    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6528class RegexpReplace(Func):
6529    arg_types = {
6530        "this": True,
6531        "expression": True,
6532        "replacement": False,
6533        "position": False,
6534        "occurrence": False,
6535        "modifiers": False,
6536    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6539class RegexpLike(Binary, Func):
6540    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6543class RegexpILike(Binary, Func):
6544    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6549class RegexpSplit(Func):
6550    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6553class Repeat(Func):
6554    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6559class Round(Func):
6560    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6563class RowNumber(Func):
6564    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6567class SafeDivide(Func):
6568    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6571class SHA(Func):
6572    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6575class SHA2(Func):
6576    _sql_names = ["SHA2"]
6577    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6580class Sign(Func):
6581    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6584class SortArray(Func):
6585    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6588class Split(Func):
6589    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6593class SplitPart(Func):
6594    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6599class Substring(Func):
6600    _sql_names = ["SUBSTRING", "SUBSTR"]
6601    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6604class StandardHash(Func):
6605    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6608class StartsWith(Func):
6609    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6610    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6613class StrPosition(Func):
6614    arg_types = {
6615        "this": True,
6616        "substr": True,
6617        "position": False,
6618        "occurrence": False,
6619    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6622class StrToDate(Func):
6623    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6626class StrToTime(Func):
6627    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):
6632class StrToUnix(Func):
6633    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6638class StrToMap(Func):
6639    arg_types = {
6640        "this": True,
6641        "pair_delim": False,
6642        "key_value_delim": False,
6643        "duplicate_resolution_callback": False,
6644    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6647class NumberToStr(Func):
6648    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6651class FromBase(Func):
6652    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6655class Struct(Func):
6656    arg_types = {"expressions": False}
6657    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6660class StructExtract(Func):
6661    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6666class Stuff(Func):
6667    _sql_names = ["STUFF", "INSERT"]
6668    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):
6671class Sum(AggFunc):
6672    pass
key = 'sum'
class Sqrt(Func):
6675class Sqrt(Func):
6676    pass
key = 'sqrt'
class Stddev(AggFunc):
6679class Stddev(AggFunc):
6680    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6683class StddevPop(AggFunc):
6684    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6687class StddevSamp(AggFunc):
6688    pass
key = 'stddevsamp'
class Time(Func):
6692class Time(Func):
6693    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6696class TimeToStr(Func):
6697    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):
6700class TimeToTimeStr(Func):
6701    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6704class TimeToUnix(Func):
6705    pass
key = 'timetounix'
class TimeStrToDate(Func):
6708class TimeStrToDate(Func):
6709    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6712class TimeStrToTime(Func):
6713    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6716class TimeStrToUnix(Func):
6717    pass
key = 'timestrtounix'
class Trim(Func):
6720class Trim(Func):
6721    arg_types = {
6722        "this": True,
6723        "expression": False,
6724        "position": False,
6725        "collation": False,
6726    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6729class TsOrDsAdd(Func, TimeUnit):
6730    # return_type is used to correctly cast the arguments of this expression when transpiling it
6731    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6732
6733    @property
6734    def return_type(self) -> DataType:
6735        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
6733    @property
6734    def return_type(self) -> DataType:
6735        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6738class TsOrDsDiff(Func, TimeUnit):
6739    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6742class TsOrDsToDateStr(Func):
6743    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6746class TsOrDsToDate(Func):
6747    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6750class TsOrDsToDatetime(Func):
6751    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6754class TsOrDsToTime(Func):
6755    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6758class TsOrDsToTimestamp(Func):
6759    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6762class TsOrDiToDi(Func):
6763    pass
key = 'tsorditodi'
class Unhex(Func):
6766class Unhex(Func):
6767    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6770class Unicode(Func):
6771    pass
key = 'unicode'
class UnixDate(Func):
6775class UnixDate(Func):
6776    pass
key = 'unixdate'
class UnixToStr(Func):
6779class UnixToStr(Func):
6780    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6785class UnixToTime(Func):
6786    arg_types = {
6787        "this": True,
6788        "scale": False,
6789        "zone": False,
6790        "hours": False,
6791        "minutes": False,
6792        "format": False,
6793    }
6794
6795    SECONDS = Literal.number(0)
6796    DECIS = Literal.number(1)
6797    CENTIS = Literal.number(2)
6798    MILLIS = Literal.number(3)
6799    DECIMILLIS = Literal.number(4)
6800    CENTIMILLIS = Literal.number(5)
6801    MICROS = Literal.number(6)
6802    DECIMICROS = Literal.number(7)
6803    CENTIMICROS = Literal.number(8)
6804    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):
6807class UnixToTimeStr(Func):
6808    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6811class UnixSeconds(Func):
6812    pass
key = 'unixseconds'
class Uuid(Func):
6815class Uuid(Func):
6816    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6817
6818    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6821class TimestampFromParts(Func):
6822    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6823    arg_types = {
6824        "year": True,
6825        "month": True,
6826        "day": True,
6827        "hour": True,
6828        "min": True,
6829        "sec": True,
6830        "nano": False,
6831        "zone": False,
6832        "milli": False,
6833    }
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):
6836class Upper(Func):
6837    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6840class Corr(Binary, AggFunc):
6841    pass
key = 'corr'
class Variance(AggFunc):
6844class Variance(AggFunc):
6845    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6848class VariancePop(AggFunc):
6849    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6852class CovarSamp(Binary, AggFunc):
6853    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6856class CovarPop(Binary, AggFunc):
6857    pass
key = 'covarpop'
class Week(Func):
6860class Week(Func):
6861    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6864class XMLElement(Func):
6865    _sql_names = ["XMLELEMENT"]
6866    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6869class XMLTable(Func):
6870    arg_types = {
6871        "this": True,
6872        "namespaces": False,
6873        "passing": False,
6874        "columns": False,
6875        "by_ref": False,
6876    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6879class XMLNamespace(Expression):
6880    pass
key = 'xmlnamespace'
class Year(Func):
6883class Year(Func):
6884    pass
key = 'year'
class Use(Expression):
6887class Use(Expression):
6888    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6891class Merge(DML):
6892    arg_types = {
6893        "this": True,
6894        "using": True,
6895        "on": True,
6896        "whens": True,
6897        "with": False,
6898        "returning": False,
6899    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6902class When(Expression):
6903    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):
6906class Whens(Expression):
6907    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6908
6909    arg_types = {"expressions": True}

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

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

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

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

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

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

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

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

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:
8225def rename_column(
8226    table_name: str | Table,
8227    old_column_name: str | Column,
8228    new_column_name: str | Column,
8229    exists: t.Optional[bool] = None,
8230    dialect: DialectType = None,
8231) -> Alter:
8232    """Build ALTER TABLE... RENAME COLUMN... expression
8233
8234    Args:
8235        table_name: Name of the table
8236        old_column: The old name of the column
8237        new_column: The new name of the column
8238        exists: Whether to add the `IF EXISTS` clause
8239        dialect: The dialect to parse the table/column.
8240
8241    Returns:
8242        Alter table expression
8243    """
8244    table = to_table(table_name, dialect=dialect)
8245    old_column = to_column(old_column_name, dialect=dialect)
8246    new_column = to_column(new_column_name, dialect=dialect)
8247    return Alter(
8248        this=table,
8249        kind="TABLE",
8250        actions=[
8251            RenameColumn(this=old_column, to=new_column, exists=exists),
8252        ],
8253    )

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

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

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:
8424def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8425    """Returns a case normalized table name without quotes.
8426
8427    Args:
8428        table: the table to normalize
8429        dialect: the dialect to use for normalization rules
8430        copy: whether to copy the expression.
8431
8432    Examples:
8433        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8434        'A-B.c'
8435    """
8436    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8437
8438    return ".".join(
8439        p.name
8440        for p in normalize_identifiers(
8441            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8442        ).parts
8443    )

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

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:
8679def tuple_(
8680    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8681) -> Tuple:
8682    """
8683    Returns an tuple.
8684
8685    Examples:
8686        >>> tuple_(1, 'x').sql()
8687        '(1, x)'
8688
8689    Args:
8690        expressions: the expressions to add to the tuple.
8691        copy: whether to copy the argument expressions.
8692        dialect: the source dialect.
8693        kwargs: the kwargs used to instantiate the function of interest.
8694
8695    Returns:
8696        A tuple expression.
8697    """
8698    return Tuple(
8699        expressions=[
8700            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8701            for expression in expressions
8702        ]
8703    )

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:
8706def true() -> Boolean:
8707    """
8708    Returns a true Boolean expression.
8709    """
8710    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8713def false() -> Boolean:
8714    """
8715    Returns a false Boolean expression.
8716    """
8717    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8720def null() -> Null:
8721    """
8722    Returns a Null expression.
8723    """
8724    return Null()

Returns a Null expression.

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