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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

expressions: List[Any]
157    @property
158    def expressions(self) -> t.List[t.Any]:
159        """
160        Retrieves the argument with key "expressions".
161        """
162        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

is_number: bool
185    @property
186    def is_number(self) -> bool:
187        """
188        Checks whether a Literal expression is a number.
189        """
190        return (isinstance(self, Literal) and not self.args["is_string"]) or (
191            isinstance(self, Neg) and self.this.is_number
192        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
194    def to_py(self) -> t.Any:
195        """
196        Returns a Python object equivalent of the SQL node.
197        """
198        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
200    @property
201    def is_int(self) -> bool:
202        """
203        Checks whether an expression is an integer.
204        """
205        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
207    @property
208    def is_star(self) -> bool:
209        """Checks whether an expression is a star."""
210        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
212    @property
213    def alias(self) -> str:
214        """
215        Returns the alias of the expression, or an empty string if it's not aliased.
216        """
217        if isinstance(self.args.get("alias"), TableAlias):
218            return self.args["alias"].name
219        return self.text("alias")

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

alias_column_names: List[str]
221    @property
222    def alias_column_names(self) -> t.List[str]:
223        table_alias = self.args.get("alias")
224        if not table_alias:
225            return []
226        return [c.name for c in table_alias.args.get("columns") or []]
name: str
228    @property
229    def name(self) -> str:
230        return self.text("this")
alias_or_name: str
232    @property
233    def alias_or_name(self) -> str:
234        return self.alias or self.name
output_name: str
236    @property
237    def output_name(self) -> str:
238        """
239        Name of the output column if this expression is a selection.
240
241        If the Expression has no output name, an empty string is returned.
242
243        Example:
244            >>> from sqlglot import parse_one
245            >>> parse_one("SELECT a").expressions[0].output_name
246            'a'
247            >>> parse_one("SELECT b AS c").expressions[0].output_name
248            'c'
249            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
250            ''
251        """
252        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]
254    @property
255    def type(self) -> t.Optional[DataType]:
256        return self._type
def is_type(self, *dtypes) -> bool:
264    def is_type(self, *dtypes) -> bool:
265        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
267    def is_leaf(self) -> bool:
268        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
270    @property
271    def meta(self) -> t.Dict[str, t.Any]:
272        if self._meta is None:
273            self._meta = {}
274        return self._meta
def copy(self) -> typing_extensions.Self:
310    def copy(self) -> Self:
311        """
312        Returns a deep copy of the expression.
313        """
314        return deepcopy(self)

Returns a deep copy of the expression.

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

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
421    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
422        """Yields the key and expression for all arguments, exploding list args."""
423        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
424            if type(vs) is list:
425                for v in reversed(vs) if reverse else vs:  # type: ignore
426                    if hasattr(v, "parent"):
427                        yield v
428            else:
429                if hasattr(vs, "parent"):
430                    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]:
432    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
433        """
434        Returns the first node in this tree which matches at least one of
435        the specified types.
436
437        Args:
438            expression_types: the expression type(s) to match.
439            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
440
441        Returns:
442            The node which matches the criteria or None if no such node was found.
443        """
444        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]:
446    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
447        """
448        Returns a generator object which visits all nodes in this tree and only
449        yields those that match at least one of the specified expression types.
450
451        Args:
452            expression_types: the expression type(s) to match.
453            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
454
455        Returns:
456            The generator object.
457        """
458        for expression in self.walk(bfs=bfs):
459            if isinstance(expression, expression_types):
460                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]:
462    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
463        """
464        Returns a nearest parent matching expression_types.
465
466        Args:
467            expression_types: the expression type(s) to match.
468
469        Returns:
470            The parent node.
471        """
472        ancestor = self.parent
473        while ancestor and not isinstance(ancestor, expression_types):
474            ancestor = ancestor.parent
475        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]
477    @property
478    def parent_select(self) -> t.Optional[Select]:
479        """
480        Returns the parent select statement.
481        """
482        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
484    @property
485    def same_parent(self) -> bool:
486        """Returns if the parent is the same class as itself."""
487        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
489    def root(self) -> Expression:
490        """
491        Returns the root expression of this tree.
492        """
493        expression = self
494        while expression.parent:
495            expression = expression.parent
496        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
498    def walk(
499        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
500    ) -> t.Iterator[Expression]:
501        """
502        Returns a generator object which visits all nodes in this tree.
503
504        Args:
505            bfs: if set to True the BFS traversal order will be applied,
506                otherwise the DFS traversal will be used instead.
507            prune: callable that returns True if the generator should stop traversing
508                this branch of the tree.
509
510        Returns:
511            the generator object.
512        """
513        if bfs:
514            yield from self.bfs(prune=prune)
515        else:
516            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]:
518    def dfs(
519        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
520    ) -> t.Iterator[Expression]:
521        """
522        Returns a generator object which visits all nodes in this tree in
523        the DFS (Depth-first) order.
524
525        Returns:
526            The generator object.
527        """
528        stack = [self]
529
530        while stack:
531            node = stack.pop()
532
533            yield node
534
535            if prune and prune(node):
536                continue
537
538            for v in node.iter_expressions(reverse=True):
539                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]:
541    def bfs(
542        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
543    ) -> t.Iterator[Expression]:
544        """
545        Returns a generator object which visits all nodes in this tree in
546        the BFS (Breadth-first) order.
547
548        Returns:
549            The generator object.
550        """
551        queue = deque([self])
552
553        while queue:
554            node = queue.popleft()
555
556            yield node
557
558            if prune and prune(node):
559                continue
560
561            for v in node.iter_expressions():
562                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):
564    def unnest(self):
565        """
566        Returns the first non parenthesis child or self.
567        """
568        expression = self
569        while type(expression) is Paren:
570            expression = expression.this
571        return expression

Returns the first non parenthesis child or self.

def unalias(self):
573    def unalias(self):
574        """
575        Returns the inner expression if this is an Alias.
576        """
577        if isinstance(self, Alias):
578            return self.this
579        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
581    def unnest_operands(self):
582        """
583        Returns unnested operands as a tuple.
584        """
585        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
587    def flatten(self, unnest=True):
588        """
589        Returns a generator which yields child nodes whose parents are the same class.
590
591        A AND B AND C -> [A, B, C]
592        """
593        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
594            if type(node) is not self.__class__:
595                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:
603    def to_s(self) -> str:
604        """
605        Same as __repr__, but includes additional information which can be useful
606        for debugging, like empty or missing args and the AST nodes' object IDs.
607        """
608        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:
610    def sql(self, dialect: DialectType = None, **opts) -> str:
611        """
612        Returns SQL string representation of this tree.
613
614        Args:
615            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
616            opts: other `sqlglot.generator.Generator` options.
617
618        Returns:
619            The SQL string.
620        """
621        from sqlglot.dialects import Dialect
622
623        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:
625    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
626        """
627        Visits all tree nodes (excluding already transformed ones)
628        and applies the given transformation function to each node.
629
630        Args:
631            fun: a function which takes a node as an argument and returns a
632                new transformed node or the same node without modifications. If the function
633                returns None, then the corresponding node will be removed from the syntax tree.
634            copy: if set to True a new tree instance is constructed, otherwise the tree is
635                modified in place.
636
637        Returns:
638            The transformed tree.
639        """
640        root = None
641        new_node = None
642
643        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
644            parent, arg_key, index = node.parent, node.arg_key, node.index
645            new_node = fun(node, *args, **kwargs)
646
647            if not root:
648                root = new_node
649            elif parent and arg_key and new_node is not node:
650                parent.set(arg_key, new_node, index)
651
652        assert root
653        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):
661    def replace(self, expression):
662        """
663        Swap out this expression with a new expression.
664
665        For example::
666
667            >>> tree = Select().select("x").from_("tbl")
668            >>> tree.find(Column).replace(column("y"))
669            Column(
670              this=Identifier(this=y, quoted=False))
671            >>> tree.sql()
672            'SELECT y FROM tbl'
673
674        Args:
675            expression: new node
676
677        Returns:
678            The new expression or expressions.
679        """
680        parent = self.parent
681
682        if not parent or parent is expression:
683            return expression
684
685        key = self.arg_key
686        value = parent.args.get(key)
687
688        if type(expression) is list and isinstance(value, Expression):
689            # We are trying to replace an Expression with a list, so it's assumed that
690            # the intention was to really replace the parent of this expression.
691            value.parent.replace(expression)
692        else:
693            parent.set(key, expression, self.index)
694
695        if expression is not self:
696            self.parent = None
697            self.arg_key = None
698            self.index = None
699
700        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:
702    def pop(self: E) -> E:
703        """
704        Remove this expression from its AST.
705
706        Returns:
707            The popped expression.
708        """
709        self.replace(None)
710        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
772    @classmethod
773    def load(cls, obj):
774        """
775        Load a dict (as returned by `Expression.dump`) into an Expression instance.
776        """
777        from sqlglot.serde import load
778
779        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:
781    def and_(
782        self,
783        *expressions: t.Optional[ExpOrStr],
784        dialect: DialectType = None,
785        copy: bool = True,
786        wrap: bool = True,
787        **opts,
788    ) -> Condition:
789        """
790        AND this condition with one or multiple expressions.
791
792        Example:
793            >>> condition("x=1").and_("y=1").sql()
794            'x = 1 AND y = 1'
795
796        Args:
797            *expressions: the SQL code strings to parse.
798                If an `Expression` instance is passed, it will be used as-is.
799            dialect: the dialect used to parse the input expression.
800            copy: whether to copy the involved expressions (only applies to Expressions).
801            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
802                precedence issues, but can be turned off when the produced AST is too deep and
803                causes recursion-related issues.
804            opts: other options to use to parse the input expressions.
805
806        Returns:
807            The new And condition.
808        """
809        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:
811    def or_(
812        self,
813        *expressions: t.Optional[ExpOrStr],
814        dialect: DialectType = None,
815        copy: bool = True,
816        wrap: bool = True,
817        **opts,
818    ) -> Condition:
819        """
820        OR this condition with one or multiple expressions.
821
822        Example:
823            >>> condition("x=1").or_("y=1").sql()
824            'x = 1 OR y = 1'
825
826        Args:
827            *expressions: the SQL code strings to parse.
828                If an `Expression` instance is passed, it will be used as-is.
829            dialect: the dialect used to parse the input expression.
830            copy: whether to copy the involved expressions (only applies to Expressions).
831            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
832                precedence issues, but can be turned off when the produced AST is too deep and
833                causes recursion-related issues.
834            opts: other options to use to parse the input expressions.
835
836        Returns:
837            The new Or condition.
838        """
839        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):
841    def not_(self, copy: bool = True):
842        """
843        Wrap this condition with NOT.
844
845        Example:
846            >>> condition("x=1").not_().sql()
847            'NOT x = 1'
848
849        Args:
850            copy: whether to copy this object.
851
852        Returns:
853            The new Not instance.
854        """
855        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 update_positions( self: ~E, other: Union[sqlglot.tokens.Token, Expression, NoneType] = None, **kwargs: Any) -> ~E:
857    def update_positions(
858        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
859    ) -> E:
860        """
861        Update this expression with positions from a token or other expression.
862
863        Args:
864            other: a token or expression to update this expression with.
865
866        Returns:
867            The updated expression.
868        """
869        if isinstance(other, Expression):
870            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
871        elif other is not None:
872            self.meta.update(
873                {
874                    "line": other.line,
875                    "col": other.col,
876                    "start": other.start,
877                    "end": other.end,
878                }
879            )
880        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
881        return self

Update this expression with positions from a token or other expression.

Arguments:
  • other: a token or expression to update this expression with.
Returns:

The updated expression.

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:
883    def as_(
884        self,
885        alias: str | Identifier,
886        quoted: t.Optional[bool] = None,
887        dialect: DialectType = None,
888        copy: bool = True,
889        **opts,
890    ) -> Alias:
891        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:
916    def isin(
917        self,
918        *expressions: t.Any,
919        query: t.Optional[ExpOrStr] = None,
920        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
921        copy: bool = True,
922        **opts,
923    ) -> In:
924        subquery = maybe_parse(query, copy=copy, **opts) if query else None
925        if subquery and not isinstance(subquery, Subquery):
926            subquery = subquery.subquery(copy=False)
927
928        return In(
929            this=maybe_copy(self, copy),
930            expressions=[convert(e, copy=copy) for e in expressions],
931            query=subquery,
932            unnest=(
933                Unnest(
934                    expressions=[
935                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
936                        for e in ensure_list(unnest)
937                    ]
938                )
939                if unnest
940                else None
941            ),
942        )
def between( self, low: Any, high: Any, copy: bool = True, symmetric: Optional[bool] = None, **opts) -> Between:
944    def between(
945        self,
946        low: t.Any,
947        high: t.Any,
948        copy: bool = True,
949        symmetric: t.Optional[bool] = None,
950        **opts,
951    ) -> Between:
952        between = Between(
953            this=maybe_copy(self, copy),
954            low=convert(low, copy=copy, **opts),
955            high=convert(high, copy=copy, **opts),
956        )
957        if symmetric is not None:
958            between.set("symmetric", symmetric)
959
960        return between
def is_( self, other: Union[str, Expression]) -> Is:
962    def is_(self, other: ExpOrStr) -> Is:
963        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
965    def like(self, other: ExpOrStr) -> Like:
966        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
968    def ilike(self, other: ExpOrStr) -> ILike:
969        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
971    def eq(self, other: t.Any) -> EQ:
972        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
974    def neq(self, other: t.Any) -> NEQ:
975        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
977    def rlike(self, other: ExpOrStr) -> RegexpLike:
978        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
980    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
981        div = self._binop(Div, other)
982        div.args["typed"] = typed
983        div.args["safe"] = safe
984        return div
def asc(self, nulls_first: bool = True) -> Ordered:
986    def asc(self, nulls_first: bool = True) -> Ordered:
987        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
989    def desc(self, nulls_first: bool = False) -> Ordered:
990        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):
1073class Condition(Expression):
1074    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
1081class DerivedTable(Expression):
1082    @property
1083    def selects(self) -> t.List[Expression]:
1084        return self.this.selects if isinstance(self.this, Query) else []
1085
1086    @property
1087    def named_selects(self) -> t.List[str]:
1088        return [select.output_name for select in self.selects]
selects: List[Expression]
1082    @property
1083    def selects(self) -> t.List[Expression]:
1084        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1086    @property
1087    def named_selects(self) -> t.List[str]:
1088        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1091class Query(Expression):
1092    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1093        """
1094        Returns a `Subquery` that wraps around this query.
1095
1096        Example:
1097            >>> subquery = Select().select("x").from_("tbl").subquery()
1098            >>> Select().select("x").from_(subquery).sql()
1099            'SELECT x FROM (SELECT x FROM tbl)'
1100
1101        Args:
1102            alias: an optional alias for the subquery.
1103            copy: if `False`, modify this expression instance in-place.
1104        """
1105        instance = maybe_copy(self, copy)
1106        if not isinstance(alias, Expression):
1107            alias = TableAlias(this=to_identifier(alias)) if alias else None
1108
1109        return Subquery(this=instance, alias=alias)
1110
1111    def limit(
1112        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1113    ) -> Q:
1114        """
1115        Adds a LIMIT clause to this query.
1116
1117        Example:
1118            >>> select("1").union(select("1")).limit(1).sql()
1119            'SELECT 1 UNION SELECT 1 LIMIT 1'
1120
1121        Args:
1122            expression: the SQL code string to parse.
1123                This can also be an integer.
1124                If a `Limit` instance is passed, it will be used as-is.
1125                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1126            dialect: the dialect used to parse the input expression.
1127            copy: if `False`, modify this expression instance in-place.
1128            opts: other options to use to parse the input expressions.
1129
1130        Returns:
1131            A limited Select expression.
1132        """
1133        return _apply_builder(
1134            expression=expression,
1135            instance=self,
1136            arg="limit",
1137            into=Limit,
1138            prefix="LIMIT",
1139            dialect=dialect,
1140            copy=copy,
1141            into_arg="expression",
1142            **opts,
1143        )
1144
1145    def offset(
1146        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1147    ) -> Q:
1148        """
1149        Set the OFFSET expression.
1150
1151        Example:
1152            >>> Select().from_("tbl").select("x").offset(10).sql()
1153            'SELECT x FROM tbl OFFSET 10'
1154
1155        Args:
1156            expression: the SQL code string to parse.
1157                This can also be an integer.
1158                If a `Offset` instance is passed, this is used as-is.
1159                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1160            dialect: the dialect used to parse the input expression.
1161            copy: if `False`, modify this expression instance in-place.
1162            opts: other options to use to parse the input expressions.
1163
1164        Returns:
1165            The modified Select expression.
1166        """
1167        return _apply_builder(
1168            expression=expression,
1169            instance=self,
1170            arg="offset",
1171            into=Offset,
1172            prefix="OFFSET",
1173            dialect=dialect,
1174            copy=copy,
1175            into_arg="expression",
1176            **opts,
1177        )
1178
1179    def order_by(
1180        self: Q,
1181        *expressions: t.Optional[ExpOrStr],
1182        append: bool = True,
1183        dialect: DialectType = None,
1184        copy: bool = True,
1185        **opts,
1186    ) -> Q:
1187        """
1188        Set the ORDER BY expression.
1189
1190        Example:
1191            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1192            'SELECT x FROM tbl ORDER BY x DESC'
1193
1194        Args:
1195            *expressions: the SQL code strings to parse.
1196                If a `Group` instance is passed, this is used as-is.
1197                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1198            append: if `True`, add to any existing expressions.
1199                Otherwise, this flattens all the `Order` expression into a single expression.
1200            dialect: the dialect used to parse the input expression.
1201            copy: if `False`, modify this expression instance in-place.
1202            opts: other options to use to parse the input expressions.
1203
1204        Returns:
1205            The modified Select expression.
1206        """
1207        return _apply_child_list_builder(
1208            *expressions,
1209            instance=self,
1210            arg="order",
1211            append=append,
1212            copy=copy,
1213            prefix="ORDER BY",
1214            into=Order,
1215            dialect=dialect,
1216            **opts,
1217        )
1218
1219    @property
1220    def ctes(self) -> t.List[CTE]:
1221        """Returns a list of all the CTEs attached to this query."""
1222        with_ = self.args.get("with")
1223        return with_.expressions if with_ else []
1224
1225    @property
1226    def selects(self) -> t.List[Expression]:
1227        """Returns the query's projections."""
1228        raise NotImplementedError("Query objects must implement `selects`")
1229
1230    @property
1231    def named_selects(self) -> t.List[str]:
1232        """Returns the output names of the query's projections."""
1233        raise NotImplementedError("Query objects must implement `named_selects`")
1234
1235    def select(
1236        self: Q,
1237        *expressions: t.Optional[ExpOrStr],
1238        append: bool = True,
1239        dialect: DialectType = None,
1240        copy: bool = True,
1241        **opts,
1242    ) -> Q:
1243        """
1244        Append to or set the SELECT expressions.
1245
1246        Example:
1247            >>> Select().select("x", "y").sql()
1248            'SELECT x, y'
1249
1250        Args:
1251            *expressions: the SQL code strings to parse.
1252                If an `Expression` instance is passed, it will be used as-is.
1253            append: if `True`, add to any existing expressions.
1254                Otherwise, this resets the expressions.
1255            dialect: the dialect used to parse the input expressions.
1256            copy: if `False`, modify this expression instance in-place.
1257            opts: other options to use to parse the input expressions.
1258
1259        Returns:
1260            The modified Query expression.
1261        """
1262        raise NotImplementedError("Query objects must implement `select`")
1263
1264    def where(
1265        self: Q,
1266        *expressions: t.Optional[ExpOrStr],
1267        append: bool = True,
1268        dialect: DialectType = None,
1269        copy: bool = True,
1270        **opts,
1271    ) -> Q:
1272        """
1273        Append to or set the WHERE expressions.
1274
1275        Examples:
1276            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1277            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1278
1279        Args:
1280            *expressions: the SQL code strings to parse.
1281                If an `Expression` instance is passed, it will be used as-is.
1282                Multiple expressions are combined with an AND operator.
1283            append: if `True`, AND the new expressions to any existing expression.
1284                Otherwise, this resets the expression.
1285            dialect: the dialect used to parse the input expressions.
1286            copy: if `False`, modify this expression instance in-place.
1287            opts: other options to use to parse the input expressions.
1288
1289        Returns:
1290            The modified expression.
1291        """
1292        return _apply_conjunction_builder(
1293            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1294            instance=self,
1295            arg="where",
1296            append=append,
1297            into=Where,
1298            dialect=dialect,
1299            copy=copy,
1300            **opts,
1301        )
1302
1303    def with_(
1304        self: Q,
1305        alias: ExpOrStr,
1306        as_: ExpOrStr,
1307        recursive: t.Optional[bool] = None,
1308        materialized: t.Optional[bool] = None,
1309        append: bool = True,
1310        dialect: DialectType = None,
1311        copy: bool = True,
1312        scalar: bool = False,
1313        **opts,
1314    ) -> Q:
1315        """
1316        Append to or set the common table expressions.
1317
1318        Example:
1319            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1320            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1321
1322        Args:
1323            alias: the SQL code string to parse as the table name.
1324                If an `Expression` instance is passed, this is used as-is.
1325            as_: the SQL code string to parse as the table expression.
1326                If an `Expression` instance is passed, it will be used as-is.
1327            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1328            materialized: set the MATERIALIZED part of the expression.
1329            append: if `True`, add to any existing expressions.
1330                Otherwise, this resets the expressions.
1331            dialect: the dialect used to parse the input expression.
1332            copy: if `False`, modify this expression instance in-place.
1333            scalar: if `True`, this is a scalar common table expression.
1334            opts: other options to use to parse the input expressions.
1335
1336        Returns:
1337            The modified expression.
1338        """
1339        return _apply_cte_builder(
1340            self,
1341            alias,
1342            as_,
1343            recursive=recursive,
1344            materialized=materialized,
1345            append=append,
1346            dialect=dialect,
1347            copy=copy,
1348            scalar=scalar,
1349            **opts,
1350        )
1351
1352    def union(
1353        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1354    ) -> Union:
1355        """
1356        Builds a UNION expression.
1357
1358        Example:
1359            >>> import sqlglot
1360            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1361            'SELECT * FROM foo UNION SELECT * FROM bla'
1362
1363        Args:
1364            expressions: the SQL code strings.
1365                If `Expression` instances are passed, they will be used as-is.
1366            distinct: set the DISTINCT flag if and only if this is true.
1367            dialect: the dialect used to parse the input expression.
1368            opts: other options to use to parse the input expressions.
1369
1370        Returns:
1371            The new Union expression.
1372        """
1373        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1374
1375    def intersect(
1376        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1377    ) -> Intersect:
1378        """
1379        Builds an INTERSECT expression.
1380
1381        Example:
1382            >>> import sqlglot
1383            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1384            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1385
1386        Args:
1387            expressions: the SQL code strings.
1388                If `Expression` instances are passed, they will be used as-is.
1389            distinct: set the DISTINCT flag if and only if this is true.
1390            dialect: the dialect used to parse the input expression.
1391            opts: other options to use to parse the input expressions.
1392
1393        Returns:
1394            The new Intersect expression.
1395        """
1396        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1397
1398    def except_(
1399        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1400    ) -> Except:
1401        """
1402        Builds an EXCEPT expression.
1403
1404        Example:
1405            >>> import sqlglot
1406            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1407            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1408
1409        Args:
1410            expressions: the SQL code strings.
1411                If `Expression` instance are passed, they will be used as-is.
1412            distinct: set the DISTINCT flag if and only if this is true.
1413            dialect: the dialect used to parse the input expression.
1414            opts: other options to use to parse the input expressions.
1415
1416        Returns:
1417            The new Except expression.
1418        """
1419        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1092    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1093        """
1094        Returns a `Subquery` that wraps around this query.
1095
1096        Example:
1097            >>> subquery = Select().select("x").from_("tbl").subquery()
1098            >>> Select().select("x").from_(subquery).sql()
1099            'SELECT x FROM (SELECT x FROM tbl)'
1100
1101        Args:
1102            alias: an optional alias for the subquery.
1103            copy: if `False`, modify this expression instance in-place.
1104        """
1105        instance = maybe_copy(self, copy)
1106        if not isinstance(alias, Expression):
1107            alias = TableAlias(this=to_identifier(alias)) if alias else None
1108
1109        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:
1111    def limit(
1112        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1113    ) -> Q:
1114        """
1115        Adds a LIMIT clause to this query.
1116
1117        Example:
1118            >>> select("1").union(select("1")).limit(1).sql()
1119            'SELECT 1 UNION SELECT 1 LIMIT 1'
1120
1121        Args:
1122            expression: the SQL code string to parse.
1123                This can also be an integer.
1124                If a `Limit` instance is passed, it will be used as-is.
1125                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1126            dialect: the dialect used to parse the input expression.
1127            copy: if `False`, modify this expression instance in-place.
1128            opts: other options to use to parse the input expressions.
1129
1130        Returns:
1131            A limited Select expression.
1132        """
1133        return _apply_builder(
1134            expression=expression,
1135            instance=self,
1136            arg="limit",
1137            into=Limit,
1138            prefix="LIMIT",
1139            dialect=dialect,
1140            copy=copy,
1141            into_arg="expression",
1142            **opts,
1143        )

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:
1145    def offset(
1146        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1147    ) -> Q:
1148        """
1149        Set the OFFSET expression.
1150
1151        Example:
1152            >>> Select().from_("tbl").select("x").offset(10).sql()
1153            'SELECT x FROM tbl OFFSET 10'
1154
1155        Args:
1156            expression: the SQL code string to parse.
1157                This can also be an integer.
1158                If a `Offset` instance is passed, this is used as-is.
1159                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1160            dialect: the dialect used to parse the input expression.
1161            copy: if `False`, modify this expression instance in-place.
1162            opts: other options to use to parse the input expressions.
1163
1164        Returns:
1165            The modified Select expression.
1166        """
1167        return _apply_builder(
1168            expression=expression,
1169            instance=self,
1170            arg="offset",
1171            into=Offset,
1172            prefix="OFFSET",
1173            dialect=dialect,
1174            copy=copy,
1175            into_arg="expression",
1176            **opts,
1177        )

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:
1179    def order_by(
1180        self: Q,
1181        *expressions: t.Optional[ExpOrStr],
1182        append: bool = True,
1183        dialect: DialectType = None,
1184        copy: bool = True,
1185        **opts,
1186    ) -> Q:
1187        """
1188        Set the ORDER BY expression.
1189
1190        Example:
1191            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1192            'SELECT x FROM tbl ORDER BY x DESC'
1193
1194        Args:
1195            *expressions: the SQL code strings to parse.
1196                If a `Group` instance is passed, this is used as-is.
1197                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1198            append: if `True`, add to any existing expressions.
1199                Otherwise, this flattens all the `Order` expression into a single expression.
1200            dialect: the dialect used to parse the input expression.
1201            copy: if `False`, modify this expression instance in-place.
1202            opts: other options to use to parse the input expressions.
1203
1204        Returns:
1205            The modified Select expression.
1206        """
1207        return _apply_child_list_builder(
1208            *expressions,
1209            instance=self,
1210            arg="order",
1211            append=append,
1212            copy=copy,
1213            prefix="ORDER BY",
1214            into=Order,
1215            dialect=dialect,
1216            **opts,
1217        )

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]
1219    @property
1220    def ctes(self) -> t.List[CTE]:
1221        """Returns a list of all the CTEs attached to this query."""
1222        with_ = self.args.get("with")
1223        return with_.expressions if with_ else []

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

selects: List[Expression]
1225    @property
1226    def selects(self) -> t.List[Expression]:
1227        """Returns the query's projections."""
1228        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1230    @property
1231    def named_selects(self) -> t.List[str]:
1232        """Returns the output names of the query's projections."""
1233        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:
1235    def select(
1236        self: Q,
1237        *expressions: t.Optional[ExpOrStr],
1238        append: bool = True,
1239        dialect: DialectType = None,
1240        copy: bool = True,
1241        **opts,
1242    ) -> Q:
1243        """
1244        Append to or set the SELECT expressions.
1245
1246        Example:
1247            >>> Select().select("x", "y").sql()
1248            'SELECT x, y'
1249
1250        Args:
1251            *expressions: the SQL code strings to parse.
1252                If an `Expression` instance is passed, it will be used as-is.
1253            append: if `True`, add to any existing expressions.
1254                Otherwise, this resets the expressions.
1255            dialect: the dialect used to parse the input expressions.
1256            copy: if `False`, modify this expression instance in-place.
1257            opts: other options to use to parse the input expressions.
1258
1259        Returns:
1260            The modified Query expression.
1261        """
1262        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 where( 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:
1264    def where(
1265        self: Q,
1266        *expressions: t.Optional[ExpOrStr],
1267        append: bool = True,
1268        dialect: DialectType = None,
1269        copy: bool = True,
1270        **opts,
1271    ) -> Q:
1272        """
1273        Append to or set the WHERE expressions.
1274
1275        Examples:
1276            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1277            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1278
1279        Args:
1280            *expressions: the SQL code strings to parse.
1281                If an `Expression` instance is passed, it will be used as-is.
1282                Multiple expressions are combined with an AND operator.
1283            append: if `True`, AND the new expressions to any existing expression.
1284                Otherwise, this resets the expression.
1285            dialect: the dialect used to parse the input expressions.
1286            copy: if `False`, modify this expression instance in-place.
1287            opts: other options to use to parse the input expressions.
1288
1289        Returns:
1290            The modified expression.
1291        """
1292        return _apply_conjunction_builder(
1293            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1294            instance=self,
1295            arg="where",
1296            append=append,
1297            into=Where,
1298            dialect=dialect,
1299            copy=copy,
1300            **opts,
1301        )

Append to or set the WHERE expressions.

Examples:
>>> 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:

The modified 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:
1303    def with_(
1304        self: Q,
1305        alias: ExpOrStr,
1306        as_: ExpOrStr,
1307        recursive: t.Optional[bool] = None,
1308        materialized: t.Optional[bool] = None,
1309        append: bool = True,
1310        dialect: DialectType = None,
1311        copy: bool = True,
1312        scalar: bool = False,
1313        **opts,
1314    ) -> Q:
1315        """
1316        Append to or set the common table expressions.
1317
1318        Example:
1319            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1320            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1321
1322        Args:
1323            alias: the SQL code string to parse as the table name.
1324                If an `Expression` instance is passed, this is used as-is.
1325            as_: the SQL code string to parse as the table expression.
1326                If an `Expression` instance is passed, it will be used as-is.
1327            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1328            materialized: set the MATERIALIZED part of the expression.
1329            append: if `True`, add to any existing expressions.
1330                Otherwise, this resets the expressions.
1331            dialect: the dialect used to parse the input expression.
1332            copy: if `False`, modify this expression instance in-place.
1333            scalar: if `True`, this is a scalar common table expression.
1334            opts: other options to use to parse the input expressions.
1335
1336        Returns:
1337            The modified expression.
1338        """
1339        return _apply_cte_builder(
1340            self,
1341            alias,
1342            as_,
1343            recursive=recursive,
1344            materialized=materialized,
1345            append=append,
1346            dialect=dialect,
1347            copy=copy,
1348            scalar=scalar,
1349            **opts,
1350        )

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:
1352    def union(
1353        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1354    ) -> Union:
1355        """
1356        Builds a UNION expression.
1357
1358        Example:
1359            >>> import sqlglot
1360            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1361            'SELECT * FROM foo UNION SELECT * FROM bla'
1362
1363        Args:
1364            expressions: the SQL code strings.
1365                If `Expression` instances are passed, they will be used as-is.
1366            distinct: set the DISTINCT flag if and only if this is true.
1367            dialect: the dialect used to parse the input expression.
1368            opts: other options to use to parse the input expressions.
1369
1370        Returns:
1371            The new Union expression.
1372        """
1373        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:
1375    def intersect(
1376        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1377    ) -> Intersect:
1378        """
1379        Builds an INTERSECT expression.
1380
1381        Example:
1382            >>> import sqlglot
1383            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1384            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1385
1386        Args:
1387            expressions: the SQL code strings.
1388                If `Expression` instances are passed, they will be used as-is.
1389            distinct: set the DISTINCT flag if and only if this is true.
1390            dialect: the dialect used to parse the input expression.
1391            opts: other options to use to parse the input expressions.
1392
1393        Returns:
1394            The new Intersect expression.
1395        """
1396        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:
1398    def except_(
1399        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1400    ) -> Except:
1401        """
1402        Builds an EXCEPT expression.
1403
1404        Example:
1405            >>> import sqlglot
1406            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1407            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1408
1409        Args:
1410            expressions: the SQL code strings.
1411                If `Expression` instance are passed, they will be used as-is.
1412            distinct: set the DISTINCT flag if and only if this is true.
1413            dialect: the dialect used to parse the input expression.
1414            opts: other options to use to parse the input expressions.
1415
1416        Returns:
1417            The new Except expression.
1418        """
1419        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):
1422class UDTF(DerivedTable):
1423    @property
1424    def selects(self) -> t.List[Expression]:
1425        alias = self.args.get("alias")
1426        return alias.columns if alias else []
selects: List[Expression]
1423    @property
1424    def selects(self) -> t.List[Expression]:
1425        alias = self.args.get("alias")
1426        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1429class Cache(Expression):
1430    arg_types = {
1431        "this": True,
1432        "lazy": False,
1433        "options": False,
1434        "expression": False,
1435    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1438class Uncache(Expression):
1439    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1442class Refresh(Expression):
1443    pass
key = 'refresh'
class DDL(Expression):
1446class DDL(Expression):
1447    @property
1448    def ctes(self) -> t.List[CTE]:
1449        """Returns a list of all the CTEs attached to this statement."""
1450        with_ = self.args.get("with")
1451        return with_.expressions if with_ else []
1452
1453    @property
1454    def selects(self) -> t.List[Expression]:
1455        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1456        return self.expression.selects if isinstance(self.expression, Query) else []
1457
1458    @property
1459    def named_selects(self) -> t.List[str]:
1460        """
1461        If this statement contains a query (e.g. a CTAS), this returns the output
1462        names of the query's projections.
1463        """
1464        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1447    @property
1448    def ctes(self) -> t.List[CTE]:
1449        """Returns a list of all the CTEs attached to this statement."""
1450        with_ = self.args.get("with")
1451        return with_.expressions if with_ else []

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

selects: List[Expression]
1453    @property
1454    def selects(self) -> t.List[Expression]:
1455        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1456        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]
1458    @property
1459    def named_selects(self) -> t.List[str]:
1460        """
1461        If this statement contains a query (e.g. a CTAS), this returns the output
1462        names of the query's projections.
1463        """
1464        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 LockingStatement(Expression):
1468class LockingStatement(Expression):
1469    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'lockingstatement'
class DML(Expression):
1472class DML(Expression):
1473    def returning(
1474        self,
1475        expression: ExpOrStr,
1476        dialect: DialectType = None,
1477        copy: bool = True,
1478        **opts,
1479    ) -> "Self":
1480        """
1481        Set the RETURNING expression. Not supported by all dialects.
1482
1483        Example:
1484            >>> delete("tbl").returning("*", dialect="postgres").sql()
1485            'DELETE FROM tbl RETURNING *'
1486
1487        Args:
1488            expression: the SQL code strings to parse.
1489                If an `Expression` instance is passed, it will be used as-is.
1490            dialect: the dialect used to parse the input expressions.
1491            copy: if `False`, modify this expression instance in-place.
1492            opts: other options to use to parse the input expressions.
1493
1494        Returns:
1495            Delete: the modified expression.
1496        """
1497        return _apply_builder(
1498            expression=expression,
1499            instance=self,
1500            arg="returning",
1501            prefix="RETURNING",
1502            dialect=dialect,
1503            copy=copy,
1504            into=Returning,
1505            **opts,
1506        )
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:
1473    def returning(
1474        self,
1475        expression: ExpOrStr,
1476        dialect: DialectType = None,
1477        copy: bool = True,
1478        **opts,
1479    ) -> "Self":
1480        """
1481        Set the RETURNING expression. Not supported by all dialects.
1482
1483        Example:
1484            >>> delete("tbl").returning("*", dialect="postgres").sql()
1485            'DELETE FROM tbl RETURNING *'
1486
1487        Args:
1488            expression: the SQL code strings to parse.
1489                If an `Expression` instance is passed, it will be used as-is.
1490            dialect: the dialect used to parse the input expressions.
1491            copy: if `False`, modify this expression instance in-place.
1492            opts: other options to use to parse the input expressions.
1493
1494        Returns:
1495            Delete: the modified expression.
1496        """
1497        return _apply_builder(
1498            expression=expression,
1499            instance=self,
1500            arg="returning",
1501            prefix="RETURNING",
1502            dialect=dialect,
1503            copy=copy,
1504            into=Returning,
1505            **opts,
1506        )

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):
1509class Create(DDL):
1510    arg_types = {
1511        "with": False,
1512        "this": True,
1513        "kind": True,
1514        "expression": False,
1515        "exists": False,
1516        "properties": False,
1517        "replace": False,
1518        "refresh": False,
1519        "unique": False,
1520        "indexes": False,
1521        "no_schema_binding": False,
1522        "begin": False,
1523        "end": False,
1524        "clone": False,
1525        "concurrently": False,
1526        "clustered": False,
1527    }
1528
1529    @property
1530    def kind(self) -> t.Optional[str]:
1531        kind = self.args.get("kind")
1532        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]
1529    @property
1530    def kind(self) -> t.Optional[str]:
1531        kind = self.args.get("kind")
1532        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1535class SequenceProperties(Expression):
1536    arg_types = {
1537        "increment": False,
1538        "minvalue": False,
1539        "maxvalue": False,
1540        "cache": False,
1541        "start": False,
1542        "owned": False,
1543        "options": False,
1544    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1547class TruncateTable(Expression):
1548    arg_types = {
1549        "expressions": True,
1550        "is_database": False,
1551        "exists": False,
1552        "only": False,
1553        "cluster": False,
1554        "identity": False,
1555        "option": False,
1556        "partition": False,
1557    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1563class Clone(Expression):
1564    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1567class Describe(Expression):
1568    arg_types = {
1569        "this": True,
1570        "style": False,
1571        "kind": False,
1572        "expressions": False,
1573        "partition": False,
1574        "format": False,
1575    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1579class Attach(Expression):
1580    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1584class Detach(Expression):
1585    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1589class Summarize(Expression):
1590    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1593class Kill(Expression):
1594    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1597class Pragma(Expression):
1598    pass
key = 'pragma'
class Declare(Expression):
1601class Declare(Expression):
1602    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1605class DeclareItem(Expression):
1606    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
class Set(Expression):
1609class Set(Expression):
1610    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1613class Heredoc(Expression):
1614    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1617class SetItem(Expression):
1618    arg_types = {
1619        "this": False,
1620        "expressions": False,
1621        "kind": False,
1622        "collate": False,  # MySQL SET NAMES statement
1623        "global": False,
1624    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class QueryBand(Expression):
1627class QueryBand(Expression):
1628    arg_types = {"this": True, "scope": False, "update": False}
arg_types = {'this': True, 'scope': False, 'update': False}
key = 'queryband'
class Show(Expression):
1631class Show(Expression):
1632    arg_types = {
1633        "this": True,
1634        "history": False,
1635        "terse": False,
1636        "target": False,
1637        "offset": False,
1638        "starts_with": False,
1639        "limit": False,
1640        "from": False,
1641        "like": False,
1642        "where": False,
1643        "db": False,
1644        "scope": False,
1645        "scope_kind": False,
1646        "full": False,
1647        "mutex": False,
1648        "query": False,
1649        "channel": False,
1650        "global": False,
1651        "log": False,
1652        "position": False,
1653        "types": False,
1654        "privileges": False,
1655        "for_table": False,
1656        "for_group": False,
1657        "for_user": False,
1658        "for_role": False,
1659        "into_outfile": False,
1660        "json": False,
1661    }
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, 'for_table': False, 'for_group': False, 'for_user': False, 'for_role': False, 'into_outfile': False, 'json': False}
key = 'show'
class UserDefinedFunction(Expression):
1664class UserDefinedFunction(Expression):
1665    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1668class CharacterSet(Expression):
1669    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1672class RecursiveWithSearch(Expression):
1673    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):
1676class With(Expression):
1677    arg_types = {"expressions": True, "recursive": False, "search": False}
1678
1679    @property
1680    def recursive(self) -> bool:
1681        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1679    @property
1680    def recursive(self) -> bool:
1681        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1684class WithinGroup(Expression):
1685    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1690class CTE(DerivedTable):
1691    arg_types = {
1692        "this": True,
1693        "alias": True,
1694        "scalar": False,
1695        "materialized": False,
1696    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1699class ProjectionDef(Expression):
1700    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1703class TableAlias(Expression):
1704    arg_types = {"this": False, "columns": False}
1705
1706    @property
1707    def columns(self):
1708        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1706    @property
1707    def columns(self):
1708        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1711class BitString(Condition):
1712    pass
key = 'bitstring'
class HexString(Condition):
1715class HexString(Condition):
1716    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1719class ByteString(Condition):
1720    pass
key = 'bytestring'
class RawString(Condition):
1723class RawString(Condition):
1724    pass
key = 'rawstring'
class UnicodeString(Condition):
1727class UnicodeString(Condition):
1728    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1731class Column(Condition):
1732    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1733
1734    @property
1735    def table(self) -> str:
1736        return self.text("table")
1737
1738    @property
1739    def db(self) -> str:
1740        return self.text("db")
1741
1742    @property
1743    def catalog(self) -> str:
1744        return self.text("catalog")
1745
1746    @property
1747    def output_name(self) -> str:
1748        return self.name
1749
1750    @property
1751    def parts(self) -> t.List[Identifier]:
1752        """Return the parts of a column in order catalog, db, table, name."""
1753        return [
1754            t.cast(Identifier, self.args[part])
1755            for part in ("catalog", "db", "table", "this")
1756            if self.args.get(part)
1757        ]
1758
1759    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1760        """Converts the column into a dot expression."""
1761        parts = self.parts
1762        parent = self.parent
1763
1764        if include_dots:
1765            while isinstance(parent, Dot):
1766                parts.append(parent.expression)
1767                parent = parent.parent
1768
1769        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
1734    @property
1735    def table(self) -> str:
1736        return self.text("table")
db: str
1738    @property
1739    def db(self) -> str:
1740        return self.text("db")
catalog: str
1742    @property
1743    def catalog(self) -> str:
1744        return self.text("catalog")
output_name: str
1746    @property
1747    def output_name(self) -> str:
1748        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]
1750    @property
1751    def parts(self) -> t.List[Identifier]:
1752        """Return the parts of a column in order catalog, db, table, name."""
1753        return [
1754            t.cast(Identifier, self.args[part])
1755            for part in ("catalog", "db", "table", "this")
1756            if self.args.get(part)
1757        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1759    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1760        """Converts the column into a dot expression."""
1761        parts = self.parts
1762        parent = self.parent
1763
1764        if include_dots:
1765            while isinstance(parent, Dot):
1766                parts.append(parent.expression)
1767                parent = parent.parent
1768
1769        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1772class ColumnPosition(Expression):
1773    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1776class ColumnDef(Expression):
1777    arg_types = {
1778        "this": True,
1779        "kind": False,
1780        "constraints": False,
1781        "exists": False,
1782        "position": False,
1783        "default": False,
1784        "output": False,
1785    }
1786
1787    @property
1788    def constraints(self) -> t.List[ColumnConstraint]:
1789        return self.args.get("constraints") or []
1790
1791    @property
1792    def kind(self) -> t.Optional[DataType]:
1793        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1787    @property
1788    def constraints(self) -> t.List[ColumnConstraint]:
1789        return self.args.get("constraints") or []
kind: Optional[DataType]
1791    @property
1792    def kind(self) -> t.Optional[DataType]:
1793        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1796class AlterColumn(Expression):
1797    arg_types = {
1798        "this": True,
1799        "dtype": False,
1800        "collate": False,
1801        "using": False,
1802        "default": False,
1803        "drop": False,
1804        "comment": False,
1805        "allow_null": False,
1806        "visible": False,
1807    }
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):
1811class AlterIndex(Expression):
1812    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1816class AlterDistStyle(Expression):
1817    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1820class AlterSortKey(Expression):
1821    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1824class AlterSet(Expression):
1825    arg_types = {
1826        "expressions": False,
1827        "option": False,
1828        "tablespace": False,
1829        "access_method": False,
1830        "file_format": False,
1831        "copy_options": False,
1832        "tag": False,
1833        "location": False,
1834        "serde": False,
1835    }
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):
1838class RenameColumn(Expression):
1839    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1842class AlterRename(Expression):
1843    pass
key = 'alterrename'
class SwapTable(Expression):
1846class SwapTable(Expression):
1847    pass
key = 'swaptable'
class Comment(Expression):
1850class Comment(Expression):
1851    arg_types = {
1852        "this": True,
1853        "kind": True,
1854        "expression": True,
1855        "exists": False,
1856        "materialized": False,
1857    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1860class Comprehension(Expression):
1861    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):
1865class MergeTreeTTLAction(Expression):
1866    arg_types = {
1867        "this": True,
1868        "delete": False,
1869        "recompress": False,
1870        "to_disk": False,
1871        "to_volume": False,
1872    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1876class MergeTreeTTL(Expression):
1877    arg_types = {
1878        "expressions": True,
1879        "where": False,
1880        "group": False,
1881        "aggregates": False,
1882    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1886class IndexConstraintOption(Expression):
1887    arg_types = {
1888        "key_block_size": False,
1889        "using": False,
1890        "parser": False,
1891        "comment": False,
1892        "visible": False,
1893        "engine_attr": False,
1894        "secondary_engine_attr": False,
1895    }
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):
1898class ColumnConstraint(Expression):
1899    arg_types = {"this": False, "kind": True}
1900
1901    @property
1902    def kind(self) -> ColumnConstraintKind:
1903        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1901    @property
1902    def kind(self) -> ColumnConstraintKind:
1903        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1906class ColumnConstraintKind(Expression):
1907    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1910class AutoIncrementColumnConstraint(ColumnConstraintKind):
1911    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1914class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1915    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1918class CaseSpecificColumnConstraint(ColumnConstraintKind):
1919    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1922class CharacterSetColumnConstraint(ColumnConstraintKind):
1923    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1926class CheckColumnConstraint(ColumnConstraintKind):
1927    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1930class ClusteredColumnConstraint(ColumnConstraintKind):
1931    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1934class CollateColumnConstraint(ColumnConstraintKind):
1935    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1938class CommentColumnConstraint(ColumnConstraintKind):
1939    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1942class CompressColumnConstraint(ColumnConstraintKind):
1943    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1946class DateFormatColumnConstraint(ColumnConstraintKind):
1947    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1950class DefaultColumnConstraint(ColumnConstraintKind):
1951    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1954class EncodeColumnConstraint(ColumnConstraintKind):
1955    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1959class ExcludeColumnConstraint(ColumnConstraintKind):
1960    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1963class EphemeralColumnConstraint(ColumnConstraintKind):
1964    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1967class WithOperator(Expression):
1968    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1971class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1972    # this: True -> ALWAYS, this: False -> BY DEFAULT
1973    arg_types = {
1974        "this": False,
1975        "expression": False,
1976        "on_null": False,
1977        "start": False,
1978        "increment": False,
1979        "minvalue": False,
1980        "maxvalue": False,
1981        "cycle": False,
1982        "order": False,
1983    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False, 'order': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1986class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1987    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1992class IndexColumnConstraint(ColumnConstraintKind):
1993    arg_types = {
1994        "this": False,
1995        "expressions": False,
1996        "kind": False,
1997        "index_type": False,
1998        "options": False,
1999        "expression": False,  # Clickhouse
2000        "granularity": False,
2001    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
2004class InlineLengthColumnConstraint(ColumnConstraintKind):
2005    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
2008class NonClusteredColumnConstraint(ColumnConstraintKind):
2009    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
2012class NotForReplicationColumnConstraint(ColumnConstraintKind):
2013    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2017class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2018    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
2021class NotNullColumnConstraint(ColumnConstraintKind):
2022    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
2026class OnUpdateColumnConstraint(ColumnConstraintKind):
2027    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2030class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2031    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2034class TitleColumnConstraint(ColumnConstraintKind):
2035    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2038class UniqueColumnConstraint(ColumnConstraintKind):
2039    arg_types = {
2040        "this": False,
2041        "index_type": False,
2042        "on_conflict": False,
2043        "nulls": False,
2044        "options": False,
2045    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2048class UppercaseColumnConstraint(ColumnConstraintKind):
2049    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2053class WatermarkColumnConstraint(Expression):
2054    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2057class PathColumnConstraint(ColumnConstraintKind):
2058    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2062class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2063    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2068class ComputedColumnConstraint(ColumnConstraintKind):
2069    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2072class Constraint(Expression):
2073    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2076class Delete(DML):
2077    arg_types = {
2078        "with": False,
2079        "this": False,
2080        "using": False,
2081        "where": False,
2082        "returning": False,
2083        "limit": False,
2084        "tables": False,  # Multiple-Table Syntax (MySQL)
2085        "cluster": False,  # Clickhouse
2086    }
2087
2088    def delete(
2089        self,
2090        table: ExpOrStr,
2091        dialect: DialectType = None,
2092        copy: bool = True,
2093        **opts,
2094    ) -> Delete:
2095        """
2096        Create a DELETE expression or replace the table on an existing DELETE expression.
2097
2098        Example:
2099            >>> delete("tbl").sql()
2100            'DELETE FROM tbl'
2101
2102        Args:
2103            table: the table from which to delete.
2104            dialect: the dialect used to parse the input expression.
2105            copy: if `False`, modify this expression instance in-place.
2106            opts: other options to use to parse the input expressions.
2107
2108        Returns:
2109            Delete: the modified expression.
2110        """
2111        return _apply_builder(
2112            expression=table,
2113            instance=self,
2114            arg="this",
2115            dialect=dialect,
2116            into=Table,
2117            copy=copy,
2118            **opts,
2119        )
2120
2121    def where(
2122        self,
2123        *expressions: t.Optional[ExpOrStr],
2124        append: bool = True,
2125        dialect: DialectType = None,
2126        copy: bool = True,
2127        **opts,
2128    ) -> Delete:
2129        """
2130        Append to or set the WHERE expressions.
2131
2132        Example:
2133            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2134            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2135
2136        Args:
2137            *expressions: the SQL code strings to parse.
2138                If an `Expression` instance is passed, it will be used as-is.
2139                Multiple expressions are combined with an AND operator.
2140            append: if `True`, AND the new expressions to any existing expression.
2141                Otherwise, this resets the expression.
2142            dialect: the dialect used to parse the input expressions.
2143            copy: if `False`, modify this expression instance in-place.
2144            opts: other options to use to parse the input expressions.
2145
2146        Returns:
2147            Delete: the modified expression.
2148        """
2149        return _apply_conjunction_builder(
2150            *expressions,
2151            instance=self,
2152            arg="where",
2153            append=append,
2154            into=Where,
2155            dialect=dialect,
2156            copy=copy,
2157            **opts,
2158        )
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:
2088    def delete(
2089        self,
2090        table: ExpOrStr,
2091        dialect: DialectType = None,
2092        copy: bool = True,
2093        **opts,
2094    ) -> Delete:
2095        """
2096        Create a DELETE expression or replace the table on an existing DELETE expression.
2097
2098        Example:
2099            >>> delete("tbl").sql()
2100            'DELETE FROM tbl'
2101
2102        Args:
2103            table: the table from which to delete.
2104            dialect: the dialect used to parse the input expression.
2105            copy: if `False`, modify this expression instance in-place.
2106            opts: other options to use to parse the input expressions.
2107
2108        Returns:
2109            Delete: the modified expression.
2110        """
2111        return _apply_builder(
2112            expression=table,
2113            instance=self,
2114            arg="this",
2115            dialect=dialect,
2116            into=Table,
2117            copy=copy,
2118            **opts,
2119        )

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:
2121    def where(
2122        self,
2123        *expressions: t.Optional[ExpOrStr],
2124        append: bool = True,
2125        dialect: DialectType = None,
2126        copy: bool = True,
2127        **opts,
2128    ) -> Delete:
2129        """
2130        Append to or set the WHERE expressions.
2131
2132        Example:
2133            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2134            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2135
2136        Args:
2137            *expressions: the SQL code strings to parse.
2138                If an `Expression` instance is passed, it will be used as-is.
2139                Multiple expressions are combined with an AND operator.
2140            append: if `True`, AND the new expressions to any existing expression.
2141                Otherwise, this resets the expression.
2142            dialect: the dialect used to parse the input expressions.
2143            copy: if `False`, modify this expression instance in-place.
2144            opts: other options to use to parse the input expressions.
2145
2146        Returns:
2147            Delete: the modified expression.
2148        """
2149        return _apply_conjunction_builder(
2150            *expressions,
2151            instance=self,
2152            arg="where",
2153            append=append,
2154            into=Where,
2155            dialect=dialect,
2156            copy=copy,
2157            **opts,
2158        )

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):
2161class Drop(Expression):
2162    arg_types = {
2163        "this": False,
2164        "kind": False,
2165        "expressions": False,
2166        "exists": False,
2167        "temporary": False,
2168        "materialized": False,
2169        "cascade": False,
2170        "constraints": False,
2171        "purge": False,
2172        "cluster": False,
2173        "concurrently": False,
2174    }
2175
2176    @property
2177    def kind(self) -> t.Optional[str]:
2178        kind = self.args.get("kind")
2179        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]
2176    @property
2177    def kind(self) -> t.Optional[str]:
2178        kind = self.args.get("kind")
2179        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2183class Export(Expression):
2184    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2187class Filter(Expression):
2188    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2191class Check(Expression):
2192    pass
key = 'check'
class Changes(Expression):
2195class Changes(Expression):
2196    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2200class Connect(Expression):
2201    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2204class CopyParameter(Expression):
2205    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2208class Copy(DML):
2209    arg_types = {
2210        "this": True,
2211        "kind": True,
2212        "files": False,
2213        "credentials": False,
2214        "format": False,
2215        "params": False,
2216    }
arg_types = {'this': True, 'kind': True, 'files': False, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2219class Credentials(Expression):
2220    arg_types = {
2221        "credentials": False,
2222        "encryption": False,
2223        "storage": False,
2224        "iam_role": False,
2225        "region": False,
2226    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2229class Prior(Expression):
2230    pass
key = 'prior'
class Directory(Expression):
2233class Directory(Expression):
2234    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2235    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2238class ForeignKey(Expression):
2239    arg_types = {
2240        "expressions": False,
2241        "reference": False,
2242        "delete": False,
2243        "update": False,
2244        "options": False,
2245    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2248class ColumnPrefix(Expression):
2249    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2252class PrimaryKey(Expression):
2253    arg_types = {"expressions": True, "options": False, "include": False}
arg_types = {'expressions': True, 'options': False, 'include': False}
key = 'primarykey'
class Into(Expression):
2258class Into(Expression):
2259    arg_types = {
2260        "this": False,
2261        "temporary": False,
2262        "unlogged": False,
2263        "bulk_collect": False,
2264        "expressions": False,
2265    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2268class From(Expression):
2269    @property
2270    def name(self) -> str:
2271        return self.this.name
2272
2273    @property
2274    def alias_or_name(self) -> str:
2275        return self.this.alias_or_name
name: str
2269    @property
2270    def name(self) -> str:
2271        return self.this.name
alias_or_name: str
2273    @property
2274    def alias_or_name(self) -> str:
2275        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2278class Having(Expression):
2279    pass
key = 'having'
class Hint(Expression):
2282class Hint(Expression):
2283    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2286class JoinHint(Expression):
2287    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2290class Identifier(Expression):
2291    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2292
2293    @property
2294    def quoted(self) -> bool:
2295        return bool(self.args.get("quoted"))
2296
2297    @property
2298    def hashable_args(self) -> t.Any:
2299        return (self.this, self.quoted)
2300
2301    @property
2302    def output_name(self) -> str:
2303        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2293    @property
2294    def quoted(self) -> bool:
2295        return bool(self.args.get("quoted"))
hashable_args: Any
2297    @property
2298    def hashable_args(self) -> t.Any:
2299        return (self.this, self.quoted)
output_name: str
2301    @property
2302    def output_name(self) -> str:
2303        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):
2307class Opclass(Expression):
2308    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2311class Index(Expression):
2312    arg_types = {
2313        "this": False,
2314        "table": False,
2315        "unique": False,
2316        "primary": False,
2317        "amp": False,  # teradata
2318        "params": False,
2319    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2322class IndexParameters(Expression):
2323    arg_types = {
2324        "using": False,
2325        "include": False,
2326        "columns": False,
2327        "with_storage": False,
2328        "partition_by": False,
2329        "tablespace": False,
2330        "where": False,
2331        "on": False,
2332    }
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):
2335class Insert(DDL, DML):
2336    arg_types = {
2337        "hint": False,
2338        "with": False,
2339        "is_function": False,
2340        "this": False,
2341        "expression": False,
2342        "conflict": False,
2343        "returning": False,
2344        "overwrite": False,
2345        "exists": False,
2346        "alternative": False,
2347        "where": False,
2348        "ignore": False,
2349        "by_name": False,
2350        "stored": False,
2351        "partition": False,
2352        "settings": False,
2353        "source": False,
2354    }
2355
2356    def with_(
2357        self,
2358        alias: ExpOrStr,
2359        as_: ExpOrStr,
2360        recursive: t.Optional[bool] = None,
2361        materialized: t.Optional[bool] = None,
2362        append: bool = True,
2363        dialect: DialectType = None,
2364        copy: bool = True,
2365        **opts,
2366    ) -> Insert:
2367        """
2368        Append to or set the common table expressions.
2369
2370        Example:
2371            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2372            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2373
2374        Args:
2375            alias: the SQL code string to parse as the table name.
2376                If an `Expression` instance is passed, this is used as-is.
2377            as_: the SQL code string to parse as the table expression.
2378                If an `Expression` instance is passed, it will be used as-is.
2379            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2380            materialized: set the MATERIALIZED part of the expression.
2381            append: if `True`, add to any existing expressions.
2382                Otherwise, this resets the expressions.
2383            dialect: the dialect used to parse the input expression.
2384            copy: if `False`, modify this expression instance in-place.
2385            opts: other options to use to parse the input expressions.
2386
2387        Returns:
2388            The modified expression.
2389        """
2390        return _apply_cte_builder(
2391            self,
2392            alias,
2393            as_,
2394            recursive=recursive,
2395            materialized=materialized,
2396            append=append,
2397            dialect=dialect,
2398            copy=copy,
2399            **opts,
2400        )
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:
2356    def with_(
2357        self,
2358        alias: ExpOrStr,
2359        as_: ExpOrStr,
2360        recursive: t.Optional[bool] = None,
2361        materialized: t.Optional[bool] = None,
2362        append: bool = True,
2363        dialect: DialectType = None,
2364        copy: bool = True,
2365        **opts,
2366    ) -> Insert:
2367        """
2368        Append to or set the common table expressions.
2369
2370        Example:
2371            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2372            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2373
2374        Args:
2375            alias: the SQL code string to parse as the table name.
2376                If an `Expression` instance is passed, this is used as-is.
2377            as_: the SQL code string to parse as the table expression.
2378                If an `Expression` instance is passed, it will be used as-is.
2379            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2380            materialized: set the MATERIALIZED part of the expression.
2381            append: if `True`, add to any existing expressions.
2382                Otherwise, this resets the expressions.
2383            dialect: the dialect used to parse the input expression.
2384            copy: if `False`, modify this expression instance in-place.
2385            opts: other options to use to parse the input expressions.
2386
2387        Returns:
2388            The modified expression.
2389        """
2390        return _apply_cte_builder(
2391            self,
2392            alias,
2393            as_,
2394            recursive=recursive,
2395            materialized=materialized,
2396            append=append,
2397            dialect=dialect,
2398            copy=copy,
2399            **opts,
2400        )

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):
2403class ConditionalInsert(Expression):
2404    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2407class MultitableInserts(Expression):
2408    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2411class OnConflict(Expression):
2412    arg_types = {
2413        "duplicate": False,
2414        "expressions": False,
2415        "action": False,
2416        "conflict_keys": False,
2417        "constraint": False,
2418        "where": False,
2419    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2422class OnCondition(Expression):
2423    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2426class Returning(Expression):
2427    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2431class Introducer(Expression):
2432    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2436class National(Expression):
2437    pass
key = 'national'
class LoadData(Expression):
2440class LoadData(Expression):
2441    arg_types = {
2442        "this": True,
2443        "local": False,
2444        "overwrite": False,
2445        "inpath": True,
2446        "partition": False,
2447        "input_format": False,
2448        "serde": False,
2449    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2452class Partition(Expression):
2453    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2456class PartitionRange(Expression):
2457    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
class PartitionId(Expression):
2461class PartitionId(Expression):
2462    pass
key = 'partitionid'
class Fetch(Expression):
2465class Fetch(Expression):
2466    arg_types = {
2467        "direction": False,
2468        "count": False,
2469        "limit_options": False,
2470    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2473class Grant(Expression):
2474    arg_types = {
2475        "privileges": True,
2476        "kind": False,
2477        "securable": True,
2478        "principals": True,
2479        "grant_option": False,
2480    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Revoke(Expression):
2483class Revoke(Expression):
2484    arg_types = {**Grant.arg_types, "cascade": False}
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False, 'cascade': False}
key = 'revoke'
class Group(Expression):
2487class Group(Expression):
2488    arg_types = {
2489        "expressions": False,
2490        "grouping_sets": False,
2491        "cube": False,
2492        "rollup": False,
2493        "totals": False,
2494        "all": False,
2495    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2498class Cube(Expression):
2499    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2502class Rollup(Expression):
2503    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2506class GroupingSets(Expression):
2507    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2510class Lambda(Expression):
2511    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2514class Limit(Expression):
2515    arg_types = {
2516        "this": False,
2517        "expression": True,
2518        "offset": False,
2519        "limit_options": False,
2520        "expressions": False,
2521    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2524class LimitOptions(Expression):
2525    arg_types = {
2526        "percent": False,
2527        "rows": False,
2528        "with_ties": False,
2529    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2532class Literal(Condition):
2533    arg_types = {"this": True, "is_string": True}
2534
2535    @property
2536    def hashable_args(self) -> t.Any:
2537        return (self.this, self.args.get("is_string"))
2538
2539    @classmethod
2540    def number(cls, number) -> Literal:
2541        return cls(this=str(number), is_string=False)
2542
2543    @classmethod
2544    def string(cls, string) -> Literal:
2545        return cls(this=str(string), is_string=True)
2546
2547    @property
2548    def output_name(self) -> str:
2549        return self.name
2550
2551    def to_py(self) -> int | str | Decimal:
2552        if self.is_number:
2553            try:
2554                return int(self.this)
2555            except ValueError:
2556                return Decimal(self.this)
2557        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2535    @property
2536    def hashable_args(self) -> t.Any:
2537        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2539    @classmethod
2540    def number(cls, number) -> Literal:
2541        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2543    @classmethod
2544    def string(cls, string) -> Literal:
2545        return cls(this=str(string), is_string=True)
output_name: str
2547    @property
2548    def output_name(self) -> str:
2549        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:
2551    def to_py(self) -> int | str | Decimal:
2552        if self.is_number:
2553            try:
2554                return int(self.this)
2555            except ValueError:
2556                return Decimal(self.this)
2557        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2560class Join(Expression):
2561    arg_types = {
2562        "this": True,
2563        "on": False,
2564        "side": False,
2565        "kind": False,
2566        "using": False,
2567        "method": False,
2568        "global": False,
2569        "hint": False,
2570        "match_condition": False,  # Snowflake
2571        "expressions": False,
2572        "pivots": False,
2573    }
2574
2575    @property
2576    def method(self) -> str:
2577        return self.text("method").upper()
2578
2579    @property
2580    def kind(self) -> str:
2581        return self.text("kind").upper()
2582
2583    @property
2584    def side(self) -> str:
2585        return self.text("side").upper()
2586
2587    @property
2588    def hint(self) -> str:
2589        return self.text("hint").upper()
2590
2591    @property
2592    def alias_or_name(self) -> str:
2593        return self.this.alias_or_name
2594
2595    @property
2596    def is_semi_or_anti_join(self) -> bool:
2597        return self.kind in ("SEMI", "ANTI")
2598
2599    def on(
2600        self,
2601        *expressions: t.Optional[ExpOrStr],
2602        append: bool = True,
2603        dialect: DialectType = None,
2604        copy: bool = True,
2605        **opts,
2606    ) -> Join:
2607        """
2608        Append to or set the ON expressions.
2609
2610        Example:
2611            >>> import sqlglot
2612            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2613            'JOIN x ON y = 1'
2614
2615        Args:
2616            *expressions: the SQL code strings to parse.
2617                If an `Expression` instance is passed, it will be used as-is.
2618                Multiple expressions are combined with an AND operator.
2619            append: if `True`, AND the new expressions to any existing expression.
2620                Otherwise, this resets the expression.
2621            dialect: the dialect used to parse the input expressions.
2622            copy: if `False`, modify this expression instance in-place.
2623            opts: other options to use to parse the input expressions.
2624
2625        Returns:
2626            The modified Join expression.
2627        """
2628        join = _apply_conjunction_builder(
2629            *expressions,
2630            instance=self,
2631            arg="on",
2632            append=append,
2633            dialect=dialect,
2634            copy=copy,
2635            **opts,
2636        )
2637
2638        if join.kind == "CROSS":
2639            join.set("kind", None)
2640
2641        return join
2642
2643    def using(
2644        self,
2645        *expressions: t.Optional[ExpOrStr],
2646        append: bool = True,
2647        dialect: DialectType = None,
2648        copy: bool = True,
2649        **opts,
2650    ) -> Join:
2651        """
2652        Append to or set the USING expressions.
2653
2654        Example:
2655            >>> import sqlglot
2656            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2657            'JOIN x USING (foo, bla)'
2658
2659        Args:
2660            *expressions: the SQL code strings to parse.
2661                If an `Expression` instance is passed, it will be used as-is.
2662            append: if `True`, concatenate the new expressions to the existing "using" list.
2663                Otherwise, this resets the expression.
2664            dialect: the dialect used to parse the input expressions.
2665            copy: if `False`, modify this expression instance in-place.
2666            opts: other options to use to parse the input expressions.
2667
2668        Returns:
2669            The modified Join expression.
2670        """
2671        join = _apply_list_builder(
2672            *expressions,
2673            instance=self,
2674            arg="using",
2675            append=append,
2676            dialect=dialect,
2677            copy=copy,
2678            **opts,
2679        )
2680
2681        if join.kind == "CROSS":
2682            join.set("kind", None)
2683
2684        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, 'pivots': False}
method: str
2575    @property
2576    def method(self) -> str:
2577        return self.text("method").upper()
kind: str
2579    @property
2580    def kind(self) -> str:
2581        return self.text("kind").upper()
side: str
2583    @property
2584    def side(self) -> str:
2585        return self.text("side").upper()
hint: str
2587    @property
2588    def hint(self) -> str:
2589        return self.text("hint").upper()
alias_or_name: str
2591    @property
2592    def alias_or_name(self) -> str:
2593        return self.this.alias_or_name
is_semi_or_anti_join: bool
2595    @property
2596    def is_semi_or_anti_join(self) -> bool:
2597        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:
2599    def on(
2600        self,
2601        *expressions: t.Optional[ExpOrStr],
2602        append: bool = True,
2603        dialect: DialectType = None,
2604        copy: bool = True,
2605        **opts,
2606    ) -> Join:
2607        """
2608        Append to or set the ON expressions.
2609
2610        Example:
2611            >>> import sqlglot
2612            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2613            'JOIN x ON y = 1'
2614
2615        Args:
2616            *expressions: the SQL code strings to parse.
2617                If an `Expression` instance is passed, it will be used as-is.
2618                Multiple expressions are combined with an AND operator.
2619            append: if `True`, AND the new expressions to any existing expression.
2620                Otherwise, this resets the expression.
2621            dialect: the dialect used to parse the input expressions.
2622            copy: if `False`, modify this expression instance in-place.
2623            opts: other options to use to parse the input expressions.
2624
2625        Returns:
2626            The modified Join expression.
2627        """
2628        join = _apply_conjunction_builder(
2629            *expressions,
2630            instance=self,
2631            arg="on",
2632            append=append,
2633            dialect=dialect,
2634            copy=copy,
2635            **opts,
2636        )
2637
2638        if join.kind == "CROSS":
2639            join.set("kind", None)
2640
2641        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:
2643    def using(
2644        self,
2645        *expressions: t.Optional[ExpOrStr],
2646        append: bool = True,
2647        dialect: DialectType = None,
2648        copy: bool = True,
2649        **opts,
2650    ) -> Join:
2651        """
2652        Append to or set the USING expressions.
2653
2654        Example:
2655            >>> import sqlglot
2656            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2657            'JOIN x USING (foo, bla)'
2658
2659        Args:
2660            *expressions: the SQL code strings to parse.
2661                If an `Expression` instance is passed, it will be used as-is.
2662            append: if `True`, concatenate the new expressions to the existing "using" list.
2663                Otherwise, this resets the expression.
2664            dialect: the dialect used to parse the input expressions.
2665            copy: if `False`, modify this expression instance in-place.
2666            opts: other options to use to parse the input expressions.
2667
2668        Returns:
2669            The modified Join expression.
2670        """
2671        join = _apply_list_builder(
2672            *expressions,
2673            instance=self,
2674            arg="using",
2675            append=append,
2676            dialect=dialect,
2677            copy=copy,
2678            **opts,
2679        )
2680
2681        if join.kind == "CROSS":
2682            join.set("kind", None)
2683
2684        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):
2687class Lateral(UDTF):
2688    arg_types = {
2689        "this": True,
2690        "view": False,
2691        "outer": False,
2692        "alias": False,
2693        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2694        "ordinality": False,
2695    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2700class TableFromRows(UDTF):
2701    arg_types = {
2702        "this": True,
2703        "alias": False,
2704        "joins": False,
2705        "pivots": False,
2706        "sample": False,
2707    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2710class MatchRecognizeMeasure(Expression):
2711    arg_types = {
2712        "this": True,
2713        "window_frame": False,
2714    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2717class MatchRecognize(Expression):
2718    arg_types = {
2719        "partition_by": False,
2720        "order": False,
2721        "measures": False,
2722        "rows": False,
2723        "after": False,
2724        "pattern": False,
2725        "define": False,
2726        "alias": False,
2727    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2732class Final(Expression):
2733    pass
key = 'final'
class Offset(Expression):
2736class Offset(Expression):
2737    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2740class Order(Expression):
2741    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2745class WithFill(Expression):
2746    arg_types = {
2747        "from": False,
2748        "to": False,
2749        "step": False,
2750        "interpolate": False,
2751    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2756class Cluster(Order):
2757    pass
key = 'cluster'
class Distribute(Order):
2760class Distribute(Order):
2761    pass
key = 'distribute'
class Sort(Order):
2764class Sort(Order):
2765    pass
key = 'sort'
class Ordered(Expression):
2768class Ordered(Expression):
2769    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2770
2771    @property
2772    def name(self) -> str:
2773        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2771    @property
2772    def name(self) -> str:
2773        return self.this.name
key = 'ordered'
class Property(Expression):
2776class Property(Expression):
2777    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2780class GrantPrivilege(Expression):
2781    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2784class GrantPrincipal(Expression):
2785    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2788class AllowedValuesProperty(Expression):
2789    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2792class AlgorithmProperty(Property):
2793    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2796class AutoIncrementProperty(Property):
2797    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2801class AutoRefreshProperty(Property):
2802    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2805class BackupProperty(Property):
2806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BuildProperty(Property):
2810class BuildProperty(Property):
2811    arg_types = {"this": True}
arg_types = {'this': True}
key = 'buildproperty'
class BlockCompressionProperty(Property):
2814class BlockCompressionProperty(Property):
2815    arg_types = {
2816        "autotemp": False,
2817        "always": False,
2818        "default": False,
2819        "manual": False,
2820        "never": False,
2821    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2824class CharacterSetProperty(Property):
2825    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2828class ChecksumProperty(Property):
2829    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2832class CollateProperty(Property):
2833    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2836class CopyGrantsProperty(Property):
2837    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2840class DataBlocksizeProperty(Property):
2841    arg_types = {
2842        "size": False,
2843        "units": False,
2844        "minimum": False,
2845        "maximum": False,
2846        "default": False,
2847    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2850class DataDeletionProperty(Property):
2851    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):
2854class DefinerProperty(Property):
2855    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2858class DistKeyProperty(Property):
2859    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2864class DistributedByProperty(Property):
2865    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):
2868class DistStyleProperty(Property):
2869    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2872class DuplicateKeyProperty(Property):
2873    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2876class EngineProperty(Property):
2877    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2880class HeapProperty(Property):
2881    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2884class ToTableProperty(Property):
2885    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2888class ExecuteAsProperty(Property):
2889    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2892class ExternalProperty(Property):
2893    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2896class FallbackProperty(Property):
2897    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2901class FileFormatProperty(Property):
2902    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2905class CredentialsProperty(Property):
2906    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2909class FreespaceProperty(Property):
2910    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2913class GlobalProperty(Property):
2914    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2917class IcebergProperty(Property):
2918    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2921class InheritsProperty(Property):
2922    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2925class InputModelProperty(Property):
2926    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2929class OutputModelProperty(Property):
2930    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2933class IsolatedLoadingProperty(Property):
2934    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2937class JournalProperty(Property):
2938    arg_types = {
2939        "no": False,
2940        "dual": False,
2941        "before": False,
2942        "local": False,
2943        "after": False,
2944    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2947class LanguageProperty(Property):
2948    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2951class EnviromentProperty(Property):
2952    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2956class ClusteredByProperty(Property):
2957    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2960class DictProperty(Property):
2961    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2964class DictSubProperty(Property):
2965    pass
key = 'dictsubproperty'
class DictRange(Property):
2968class DictRange(Property):
2969    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2972class DynamicProperty(Property):
2973    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2978class OnCluster(Property):
2979    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2983class EmptyProperty(Property):
2984    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2987class LikeProperty(Property):
2988    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2991class LocationProperty(Property):
2992    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2995class LockProperty(Property):
2996    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2999class LockingProperty(Property):
3000    arg_types = {
3001        "this": False,
3002        "kind": True,
3003        "for_or_in": False,
3004        "lock_type": True,
3005        "override": False,
3006    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
3009class LogProperty(Property):
3010    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
3013class MaterializedProperty(Property):
3014    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
3017class MergeBlockRatioProperty(Property):
3018    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):
3021class NoPrimaryIndexProperty(Property):
3022    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
3025class OnProperty(Property):
3026    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
3029class OnCommitProperty(Property):
3030    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3033class PartitionedByProperty(Property):
3034    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3037class PartitionedByBucket(Property):
3038    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3041class PartitionByTruncate(Property):
3042    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3046class PartitionByRangeProperty(Property):
3047    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3051class PartitionByRangePropertyDynamic(Expression):
3052    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class PartitionByListProperty(Property):
3056class PartitionByListProperty(Property):
3057    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbylistproperty'
class PartitionList(Expression):
3061class PartitionList(Expression):
3062    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'partitionlist'
class RefreshTriggerProperty(Property):
3066class RefreshTriggerProperty(Property):
3067    arg_types = {
3068        "method": True,
3069        "kind": False,
3070        "every": False,
3071        "unit": False,
3072        "starts": False,
3073    }
arg_types = {'method': True, 'kind': False, 'every': False, 'unit': False, 'starts': False}
key = 'refreshtriggerproperty'
class UniqueKeyProperty(Property):
3077class UniqueKeyProperty(Property):
3078    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3082class PartitionBoundSpec(Expression):
3083    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3084    arg_types = {
3085        "this": False,
3086        "expression": False,
3087        "from_expressions": False,
3088        "to_expressions": False,
3089    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3092class PartitionedOfProperty(Property):
3093    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3094    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3097class StreamingTableProperty(Property):
3098    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3101class RemoteWithConnectionModelProperty(Property):
3102    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3105class ReturnsProperty(Property):
3106    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):
3109class StrictProperty(Property):
3110    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3113class RowFormatProperty(Property):
3114    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3117class RowFormatDelimitedProperty(Property):
3118    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3119    arg_types = {
3120        "fields": False,
3121        "escaped": False,
3122        "collection_items": False,
3123        "map_keys": False,
3124        "lines": False,
3125        "null": False,
3126        "serde": False,
3127    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3130class RowFormatSerdeProperty(Property):
3131    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3135class QueryTransform(Expression):
3136    arg_types = {
3137        "expressions": True,
3138        "command_script": True,
3139        "schema": False,
3140        "row_format_before": False,
3141        "record_writer": False,
3142        "row_format_after": False,
3143        "record_reader": False,
3144    }
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):
3147class SampleProperty(Property):
3148    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3152class SecurityProperty(Property):
3153    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3156class SchemaCommentProperty(Property):
3157    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3160class SemanticView(Expression):
3161    arg_types = {"this": True, "metrics": False, "dimensions": False, "where": False}
arg_types = {'this': True, 'metrics': False, 'dimensions': False, 'where': False}
key = 'semanticview'
class SerdeProperties(Property):
3164class SerdeProperties(Property):
3165    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3168class SetProperty(Property):
3169    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3172class SharingProperty(Property):
3173    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3176class SetConfigProperty(Property):
3177    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3180class SettingsProperty(Property):
3181    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3184class SortKeyProperty(Property):
3185    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3188class SqlReadWriteProperty(Property):
3189    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3192class SqlSecurityProperty(Property):
3193    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3196class StabilityProperty(Property):
3197    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3200class StorageHandlerProperty(Property):
3201    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3204class TemporaryProperty(Property):
3205    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3208class SecureProperty(Property):
3209    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3213class Tags(ColumnConstraintKind, Property):
3214    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3217class TransformModelProperty(Property):
3218    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3221class TransientProperty(Property):
3222    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3225class UnloggedProperty(Property):
3226    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3230class UsingTemplateProperty(Property):
3231    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3235class ViewAttributeProperty(Property):
3236    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3239class VolatileProperty(Property):
3240    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3243class WithDataProperty(Property):
3244    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3247class WithJournalTableProperty(Property):
3248    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3251class WithSchemaBindingProperty(Property):
3252    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3255class WithSystemVersioningProperty(Property):
3256    arg_types = {
3257        "on": False,
3258        "this": False,
3259        "data_consistency": False,
3260        "retention_period": False,
3261        "with": True,
3262    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3265class WithProcedureOptions(Property):
3266    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3269class EncodeProperty(Property):
3270    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3273class IncludeProperty(Property):
3274    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3277class ForceProperty(Property):
3278    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3281class Properties(Expression):
3282    arg_types = {"expressions": True}
3283
3284    NAME_TO_PROPERTY = {
3285        "ALGORITHM": AlgorithmProperty,
3286        "AUTO_INCREMENT": AutoIncrementProperty,
3287        "CHARACTER SET": CharacterSetProperty,
3288        "CLUSTERED_BY": ClusteredByProperty,
3289        "COLLATE": CollateProperty,
3290        "COMMENT": SchemaCommentProperty,
3291        "CREDENTIALS": CredentialsProperty,
3292        "DEFINER": DefinerProperty,
3293        "DISTKEY": DistKeyProperty,
3294        "DISTRIBUTED_BY": DistributedByProperty,
3295        "DISTSTYLE": DistStyleProperty,
3296        "ENGINE": EngineProperty,
3297        "EXECUTE AS": ExecuteAsProperty,
3298        "FORMAT": FileFormatProperty,
3299        "LANGUAGE": LanguageProperty,
3300        "LOCATION": LocationProperty,
3301        "LOCK": LockProperty,
3302        "PARTITIONED_BY": PartitionedByProperty,
3303        "RETURNS": ReturnsProperty,
3304        "ROW_FORMAT": RowFormatProperty,
3305        "SORTKEY": SortKeyProperty,
3306        "ENCODE": EncodeProperty,
3307        "INCLUDE": IncludeProperty,
3308    }
3309
3310    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3311
3312    # CREATE property locations
3313    # Form: schema specified
3314    #   create [POST_CREATE]
3315    #     table a [POST_NAME]
3316    #     (b int) [POST_SCHEMA]
3317    #     with ([POST_WITH])
3318    #     index (b) [POST_INDEX]
3319    #
3320    # Form: alias selection
3321    #   create [POST_CREATE]
3322    #     table a [POST_NAME]
3323    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3324    #     index (c) [POST_INDEX]
3325    class Location(AutoName):
3326        POST_CREATE = auto()
3327        POST_NAME = auto()
3328        POST_SCHEMA = auto()
3329        POST_WITH = auto()
3330        POST_ALIAS = auto()
3331        POST_EXPRESSION = auto()
3332        POST_INDEX = auto()
3333        UNSUPPORTED = auto()
3334
3335    @classmethod
3336    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3337        expressions = []
3338        for key, value in properties_dict.items():
3339            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3340            if property_cls:
3341                expressions.append(property_cls(this=convert(value)))
3342            else:
3343                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3344
3345        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'CREDENTIALS': <class 'CredentialsProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>, 'ENCODE': <class 'EncodeProperty'>, 'INCLUDE': <class 'IncludeProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'CredentialsProperty'>: 'CREDENTIALS', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistributedByProperty'>: 'DISTRIBUTED_BY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY', <class 'EncodeProperty'>: 'ENCODE', <class 'IncludeProperty'>: 'INCLUDE'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3335    @classmethod
3336    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3337        expressions = []
3338        for key, value in properties_dict.items():
3339            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3340            if property_cls:
3341                expressions.append(property_cls(this=convert(value)))
3342            else:
3343                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3344
3345        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3325    class Location(AutoName):
3326        POST_CREATE = auto()
3327        POST_NAME = auto()
3328        POST_SCHEMA = auto()
3329        POST_WITH = auto()
3330        POST_ALIAS = auto()
3331        POST_EXPRESSION = auto()
3332        POST_INDEX = auto()
3333        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):
3348class Qualify(Expression):
3349    pass
key = 'qualify'
class InputOutputFormat(Expression):
3352class InputOutputFormat(Expression):
3353    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3357class Return(Expression):
3358    pass
key = 'return'
class Reference(Expression):
3361class Reference(Expression):
3362    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3365class Tuple(Expression):
3366    arg_types = {"expressions": False}
3367
3368    def isin(
3369        self,
3370        *expressions: t.Any,
3371        query: t.Optional[ExpOrStr] = None,
3372        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3373        copy: bool = True,
3374        **opts,
3375    ) -> In:
3376        return In(
3377            this=maybe_copy(self, copy),
3378            expressions=[convert(e, copy=copy) for e in expressions],
3379            query=maybe_parse(query, copy=copy, **opts) if query else None,
3380            unnest=(
3381                Unnest(
3382                    expressions=[
3383                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3384                        for e in ensure_list(unnest)
3385                    ]
3386                )
3387                if unnest
3388                else None
3389            ),
3390        )
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:
3368    def isin(
3369        self,
3370        *expressions: t.Any,
3371        query: t.Optional[ExpOrStr] = None,
3372        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3373        copy: bool = True,
3374        **opts,
3375    ) -> In:
3376        return In(
3377            this=maybe_copy(self, copy),
3378            expressions=[convert(e, copy=copy) for e in expressions],
3379            query=maybe_parse(query, copy=copy, **opts) if query else None,
3380            unnest=(
3381                Unnest(
3382                    expressions=[
3383                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3384                        for e in ensure_list(unnest)
3385                    ]
3386                )
3387                if unnest
3388                else None
3389            ),
3390        )
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):
3421class QueryOption(Expression):
3422    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3426class WithTableHint(Expression):
3427    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3431class IndexTableHint(Expression):
3432    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3436class HistoricalData(Expression):
3437    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3441class Put(Expression):
3442    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3446class Get(Expression):
3447    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3450class Table(Expression):
3451    arg_types = {
3452        "this": False,
3453        "alias": False,
3454        "db": False,
3455        "catalog": False,
3456        "laterals": False,
3457        "joins": False,
3458        "pivots": False,
3459        "hints": False,
3460        "system_time": False,
3461        "version": False,
3462        "format": False,
3463        "pattern": False,
3464        "ordinality": False,
3465        "when": False,
3466        "only": False,
3467        "partition": False,
3468        "changes": False,
3469        "rows_from": False,
3470        "sample": False,
3471    }
3472
3473    @property
3474    def name(self) -> str:
3475        if not self.this or isinstance(self.this, Func):
3476            return ""
3477        return self.this.name
3478
3479    @property
3480    def db(self) -> str:
3481        return self.text("db")
3482
3483    @property
3484    def catalog(self) -> str:
3485        return self.text("catalog")
3486
3487    @property
3488    def selects(self) -> t.List[Expression]:
3489        return []
3490
3491    @property
3492    def named_selects(self) -> t.List[str]:
3493        return []
3494
3495    @property
3496    def parts(self) -> t.List[Expression]:
3497        """Return the parts of a table in order catalog, db, table."""
3498        parts: t.List[Expression] = []
3499
3500        for arg in ("catalog", "db", "this"):
3501            part = self.args.get(arg)
3502
3503            if isinstance(part, Dot):
3504                parts.extend(part.flatten())
3505            elif isinstance(part, Expression):
3506                parts.append(part)
3507
3508        return parts
3509
3510    def to_column(self, copy: bool = True) -> Expression:
3511        parts = self.parts
3512        last_part = parts[-1]
3513
3514        if isinstance(last_part, Identifier):
3515            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3516        else:
3517            # This branch will be reached if a function or array is wrapped in a `Table`
3518            col = last_part
3519
3520        alias = self.args.get("alias")
3521        if alias:
3522            col = alias_(col, alias.this, copy=copy)
3523
3524        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
3473    @property
3474    def name(self) -> str:
3475        if not self.this or isinstance(self.this, Func):
3476            return ""
3477        return self.this.name
db: str
3479    @property
3480    def db(self) -> str:
3481        return self.text("db")
catalog: str
3483    @property
3484    def catalog(self) -> str:
3485        return self.text("catalog")
selects: List[Expression]
3487    @property
3488    def selects(self) -> t.List[Expression]:
3489        return []
named_selects: List[str]
3491    @property
3492    def named_selects(self) -> t.List[str]:
3493        return []
parts: List[Expression]
3495    @property
3496    def parts(self) -> t.List[Expression]:
3497        """Return the parts of a table in order catalog, db, table."""
3498        parts: t.List[Expression] = []
3499
3500        for arg in ("catalog", "db", "this"):
3501            part = self.args.get(arg)
3502
3503            if isinstance(part, Dot):
3504                parts.extend(part.flatten())
3505            elif isinstance(part, Expression):
3506                parts.append(part)
3507
3508        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3510    def to_column(self, copy: bool = True) -> Expression:
3511        parts = self.parts
3512        last_part = parts[-1]
3513
3514        if isinstance(last_part, Identifier):
3515            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3516        else:
3517            # This branch will be reached if a function or array is wrapped in a `Table`
3518            col = last_part
3519
3520        alias = self.args.get("alias")
3521        if alias:
3522            col = alias_(col, alias.this, copy=copy)
3523
3524        return col
key = 'table'
class SetOperation(Query):
3527class SetOperation(Query):
3528    arg_types = {
3529        "with": False,
3530        "this": True,
3531        "expression": True,
3532        "distinct": False,
3533        "by_name": False,
3534        "side": False,
3535        "kind": False,
3536        "on": False,
3537        **QUERY_MODIFIERS,
3538    }
3539
3540    def select(
3541        self: S,
3542        *expressions: t.Optional[ExpOrStr],
3543        append: bool = True,
3544        dialect: DialectType = None,
3545        copy: bool = True,
3546        **opts,
3547    ) -> S:
3548        this = maybe_copy(self, copy)
3549        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3550        this.expression.unnest().select(
3551            *expressions, append=append, dialect=dialect, copy=False, **opts
3552        )
3553        return this
3554
3555    @property
3556    def named_selects(self) -> t.List[str]:
3557        return self.this.unnest().named_selects
3558
3559    @property
3560    def is_star(self) -> bool:
3561        return self.this.is_star or self.expression.is_star
3562
3563    @property
3564    def selects(self) -> t.List[Expression]:
3565        return self.this.unnest().selects
3566
3567    @property
3568    def left(self) -> Query:
3569        return self.this
3570
3571    @property
3572    def right(self) -> Query:
3573        return self.expression
3574
3575    @property
3576    def kind(self) -> str:
3577        return self.text("kind").upper()
3578
3579    @property
3580    def side(self) -> str:
3581        return self.text("side").upper()
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3540    def select(
3541        self: S,
3542        *expressions: t.Optional[ExpOrStr],
3543        append: bool = True,
3544        dialect: DialectType = None,
3545        copy: bool = True,
3546        **opts,
3547    ) -> S:
3548        this = maybe_copy(self, copy)
3549        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3550        this.expression.unnest().select(
3551            *expressions, append=append, dialect=dialect, copy=False, **opts
3552        )
3553        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]
3555    @property
3556    def named_selects(self) -> t.List[str]:
3557        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3559    @property
3560    def is_star(self) -> bool:
3561        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3563    @property
3564    def selects(self) -> t.List[Expression]:
3565        return self.this.unnest().selects

Returns the query's projections.

left: Query
3567    @property
3568    def left(self) -> Query:
3569        return self.this
right: Query
3571    @property
3572    def right(self) -> Query:
3573        return self.expression
kind: str
3575    @property
3576    def kind(self) -> str:
3577        return self.text("kind").upper()
side: str
3579    @property
3580    def side(self) -> str:
3581        return self.text("side").upper()
key = 'setoperation'
class Union(SetOperation):
3584class Union(SetOperation):
3585    pass
key = 'union'
class Except(SetOperation):
3588class Except(SetOperation):
3589    pass
key = 'except'
class Intersect(SetOperation):
3592class Intersect(SetOperation):
3593    pass
key = 'intersect'
class Update(DML):
3596class Update(DML):
3597    arg_types = {
3598        "with": False,
3599        "this": False,
3600        "expressions": True,
3601        "from": False,
3602        "where": False,
3603        "returning": False,
3604        "order": False,
3605        "limit": False,
3606    }
3607
3608    def table(
3609        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3610    ) -> Update:
3611        """
3612        Set the table to update.
3613
3614        Example:
3615            >>> Update().table("my_table").set_("x = 1").sql()
3616            'UPDATE my_table SET x = 1'
3617
3618        Args:
3619            expression : the SQL code strings to parse.
3620                If a `Table` instance is passed, this is used as-is.
3621                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3622            dialect: the dialect used to parse the input expression.
3623            copy: if `False`, modify this expression instance in-place.
3624            opts: other options to use to parse the input expressions.
3625
3626        Returns:
3627            The modified Update expression.
3628        """
3629        return _apply_builder(
3630            expression=expression,
3631            instance=self,
3632            arg="this",
3633            into=Table,
3634            prefix=None,
3635            dialect=dialect,
3636            copy=copy,
3637            **opts,
3638        )
3639
3640    def set_(
3641        self,
3642        *expressions: ExpOrStr,
3643        append: bool = True,
3644        dialect: DialectType = None,
3645        copy: bool = True,
3646        **opts,
3647    ) -> Update:
3648        """
3649        Append to or set the SET expressions.
3650
3651        Example:
3652            >>> Update().table("my_table").set_("x = 1").sql()
3653            'UPDATE my_table SET x = 1'
3654
3655        Args:
3656            *expressions: the SQL code strings to parse.
3657                If `Expression` instance(s) are passed, they will be used as-is.
3658                Multiple expressions are combined with a comma.
3659            append: if `True`, add the new expressions to any existing SET expressions.
3660                Otherwise, this resets the expressions.
3661            dialect: the dialect used to parse the input expressions.
3662            copy: if `False`, modify this expression instance in-place.
3663            opts: other options to use to parse the input expressions.
3664        """
3665        return _apply_list_builder(
3666            *expressions,
3667            instance=self,
3668            arg="expressions",
3669            append=append,
3670            into=Expression,
3671            prefix=None,
3672            dialect=dialect,
3673            copy=copy,
3674            **opts,
3675        )
3676
3677    def where(
3678        self,
3679        *expressions: t.Optional[ExpOrStr],
3680        append: bool = True,
3681        dialect: DialectType = None,
3682        copy: bool = True,
3683        **opts,
3684    ) -> Select:
3685        """
3686        Append to or set the WHERE expressions.
3687
3688        Example:
3689            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3690            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3691
3692        Args:
3693            *expressions: the SQL code strings to parse.
3694                If an `Expression` instance is passed, it will be used as-is.
3695                Multiple expressions are combined with an AND operator.
3696            append: if `True`, AND the new expressions to any existing expression.
3697                Otherwise, this resets the expression.
3698            dialect: the dialect used to parse the input expressions.
3699            copy: if `False`, modify this expression instance in-place.
3700            opts: other options to use to parse the input expressions.
3701
3702        Returns:
3703            Select: the modified expression.
3704        """
3705        return _apply_conjunction_builder(
3706            *expressions,
3707            instance=self,
3708            arg="where",
3709            append=append,
3710            into=Where,
3711            dialect=dialect,
3712            copy=copy,
3713            **opts,
3714        )
3715
3716    def from_(
3717        self,
3718        expression: t.Optional[ExpOrStr] = None,
3719        dialect: DialectType = None,
3720        copy: bool = True,
3721        **opts,
3722    ) -> Update:
3723        """
3724        Set the FROM expression.
3725
3726        Example:
3727            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3728            'UPDATE my_table SET x = 1 FROM baz'
3729
3730        Args:
3731            expression : the SQL code strings to parse.
3732                If a `From` instance is passed, this is used as-is.
3733                If another `Expression` instance is passed, it will be wrapped in a `From`.
3734                If nothing is passed in then a from is not applied to the expression
3735            dialect: the dialect used to parse the input expression.
3736            copy: if `False`, modify this expression instance in-place.
3737            opts: other options to use to parse the input expressions.
3738
3739        Returns:
3740            The modified Update expression.
3741        """
3742        if not expression:
3743            return maybe_copy(self, copy)
3744
3745        return _apply_builder(
3746            expression=expression,
3747            instance=self,
3748            arg="from",
3749            into=From,
3750            prefix="FROM",
3751            dialect=dialect,
3752            copy=copy,
3753            **opts,
3754        )
3755
3756    def with_(
3757        self,
3758        alias: ExpOrStr,
3759        as_: ExpOrStr,
3760        recursive: t.Optional[bool] = None,
3761        materialized: t.Optional[bool] = None,
3762        append: bool = True,
3763        dialect: DialectType = None,
3764        copy: bool = True,
3765        **opts,
3766    ) -> Update:
3767        """
3768        Append to or set the common table expressions.
3769
3770        Example:
3771            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3772            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3773
3774        Args:
3775            alias: the SQL code string to parse as the table name.
3776                If an `Expression` instance is passed, this is used as-is.
3777            as_: the SQL code string to parse as the table expression.
3778                If an `Expression` instance is passed, it will be used as-is.
3779            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3780            materialized: set the MATERIALIZED part of the expression.
3781            append: if `True`, add to any existing expressions.
3782                Otherwise, this resets the expressions.
3783            dialect: the dialect used to parse the input expression.
3784            copy: if `False`, modify this expression instance in-place.
3785            opts: other options to use to parse the input expressions.
3786
3787        Returns:
3788            The modified expression.
3789        """
3790        return _apply_cte_builder(
3791            self,
3792            alias,
3793            as_,
3794            recursive=recursive,
3795            materialized=materialized,
3796            append=append,
3797            dialect=dialect,
3798            copy=copy,
3799            **opts,
3800        )
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:
3608    def table(
3609        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3610    ) -> Update:
3611        """
3612        Set the table to update.
3613
3614        Example:
3615            >>> Update().table("my_table").set_("x = 1").sql()
3616            'UPDATE my_table SET x = 1'
3617
3618        Args:
3619            expression : the SQL code strings to parse.
3620                If a `Table` instance is passed, this is used as-is.
3621                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3622            dialect: the dialect used to parse the input expression.
3623            copy: if `False`, modify this expression instance in-place.
3624            opts: other options to use to parse the input expressions.
3625
3626        Returns:
3627            The modified Update expression.
3628        """
3629        return _apply_builder(
3630            expression=expression,
3631            instance=self,
3632            arg="this",
3633            into=Table,
3634            prefix=None,
3635            dialect=dialect,
3636            copy=copy,
3637            **opts,
3638        )

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:
3640    def set_(
3641        self,
3642        *expressions: ExpOrStr,
3643        append: bool = True,
3644        dialect: DialectType = None,
3645        copy: bool = True,
3646        **opts,
3647    ) -> Update:
3648        """
3649        Append to or set the SET expressions.
3650
3651        Example:
3652            >>> Update().table("my_table").set_("x = 1").sql()
3653            'UPDATE my_table SET x = 1'
3654
3655        Args:
3656            *expressions: the SQL code strings to parse.
3657                If `Expression` instance(s) are passed, they will be used as-is.
3658                Multiple expressions are combined with a comma.
3659            append: if `True`, add the new expressions to any existing SET expressions.
3660                Otherwise, this resets the expressions.
3661            dialect: the dialect used to parse the input expressions.
3662            copy: if `False`, modify this expression instance in-place.
3663            opts: other options to use to parse the input expressions.
3664        """
3665        return _apply_list_builder(
3666            *expressions,
3667            instance=self,
3668            arg="expressions",
3669            append=append,
3670            into=Expression,
3671            prefix=None,
3672            dialect=dialect,
3673            copy=copy,
3674            **opts,
3675        )

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:
3677    def where(
3678        self,
3679        *expressions: t.Optional[ExpOrStr],
3680        append: bool = True,
3681        dialect: DialectType = None,
3682        copy: bool = True,
3683        **opts,
3684    ) -> Select:
3685        """
3686        Append to or set the WHERE expressions.
3687
3688        Example:
3689            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3690            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3691
3692        Args:
3693            *expressions: the SQL code strings to parse.
3694                If an `Expression` instance is passed, it will be used as-is.
3695                Multiple expressions are combined with an AND operator.
3696            append: if `True`, AND the new expressions to any existing expression.
3697                Otherwise, this resets the expression.
3698            dialect: the dialect used to parse the input expressions.
3699            copy: if `False`, modify this expression instance in-place.
3700            opts: other options to use to parse the input expressions.
3701
3702        Returns:
3703            Select: the modified expression.
3704        """
3705        return _apply_conjunction_builder(
3706            *expressions,
3707            instance=self,
3708            arg="where",
3709            append=append,
3710            into=Where,
3711            dialect=dialect,
3712            copy=copy,
3713            **opts,
3714        )

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:
3716    def from_(
3717        self,
3718        expression: t.Optional[ExpOrStr] = None,
3719        dialect: DialectType = None,
3720        copy: bool = True,
3721        **opts,
3722    ) -> Update:
3723        """
3724        Set the FROM expression.
3725
3726        Example:
3727            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3728            'UPDATE my_table SET x = 1 FROM baz'
3729
3730        Args:
3731            expression : the SQL code strings to parse.
3732                If a `From` instance is passed, this is used as-is.
3733                If another `Expression` instance is passed, it will be wrapped in a `From`.
3734                If nothing is passed in then a from is not applied to the expression
3735            dialect: the dialect used to parse the input expression.
3736            copy: if `False`, modify this expression instance in-place.
3737            opts: other options to use to parse the input expressions.
3738
3739        Returns:
3740            The modified Update expression.
3741        """
3742        if not expression:
3743            return maybe_copy(self, copy)
3744
3745        return _apply_builder(
3746            expression=expression,
3747            instance=self,
3748            arg="from",
3749            into=From,
3750            prefix="FROM",
3751            dialect=dialect,
3752            copy=copy,
3753            **opts,
3754        )

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:
3756    def with_(
3757        self,
3758        alias: ExpOrStr,
3759        as_: ExpOrStr,
3760        recursive: t.Optional[bool] = None,
3761        materialized: t.Optional[bool] = None,
3762        append: bool = True,
3763        dialect: DialectType = None,
3764        copy: bool = True,
3765        **opts,
3766    ) -> Update:
3767        """
3768        Append to or set the common table expressions.
3769
3770        Example:
3771            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3772            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3773
3774        Args:
3775            alias: the SQL code string to parse as the table name.
3776                If an `Expression` instance is passed, this is used as-is.
3777            as_: the SQL code string to parse as the table expression.
3778                If an `Expression` instance is passed, it will be used as-is.
3779            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3780            materialized: set the MATERIALIZED part of the expression.
3781            append: if `True`, add to any existing expressions.
3782                Otherwise, this resets the expressions.
3783            dialect: the dialect used to parse the input expression.
3784            copy: if `False`, modify this expression instance in-place.
3785            opts: other options to use to parse the input expressions.
3786
3787        Returns:
3788            The modified expression.
3789        """
3790        return _apply_cte_builder(
3791            self,
3792            alias,
3793            as_,
3794            recursive=recursive,
3795            materialized=materialized,
3796            append=append,
3797            dialect=dialect,
3798            copy=copy,
3799            **opts,
3800        )

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):
3803class Values(UDTF):
3804    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3807class Var(Expression):
3808    pass
key = 'var'
class Version(Expression):
3811class Version(Expression):
3812    """
3813    Time travel, iceberg, bigquery etc
3814    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3815    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3816    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3817    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3818    this is either TIMESTAMP or VERSION
3819    kind is ("AS OF", "BETWEEN")
3820    """
3821
3822    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3825class Schema(Expression):
3826    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3831class Lock(Expression):
3832    arg_types = {"update": True, "expressions": False, "wait": False, "key": False}
arg_types = {'update': True, 'expressions': False, 'wait': False, 'key': False}
key = 'lock'
class Select(Query):
3835class Select(Query):
3836    arg_types = {
3837        "with": False,
3838        "kind": False,
3839        "expressions": False,
3840        "hint": False,
3841        "distinct": False,
3842        "into": False,
3843        "from": False,
3844        "operation_modifiers": False,
3845        **QUERY_MODIFIERS,
3846    }
3847
3848    def from_(
3849        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3850    ) -> Select:
3851        """
3852        Set the FROM expression.
3853
3854        Example:
3855            >>> Select().from_("tbl").select("x").sql()
3856            'SELECT x FROM tbl'
3857
3858        Args:
3859            expression : the SQL code strings to parse.
3860                If a `From` instance is passed, this is used as-is.
3861                If another `Expression` instance is passed, it will be wrapped in a `From`.
3862            dialect: the dialect used to parse the input expression.
3863            copy: if `False`, modify this expression instance in-place.
3864            opts: other options to use to parse the input expressions.
3865
3866        Returns:
3867            The modified Select expression.
3868        """
3869        return _apply_builder(
3870            expression=expression,
3871            instance=self,
3872            arg="from",
3873            into=From,
3874            prefix="FROM",
3875            dialect=dialect,
3876            copy=copy,
3877            **opts,
3878        )
3879
3880    def group_by(
3881        self,
3882        *expressions: t.Optional[ExpOrStr],
3883        append: bool = True,
3884        dialect: DialectType = None,
3885        copy: bool = True,
3886        **opts,
3887    ) -> Select:
3888        """
3889        Set the GROUP BY expression.
3890
3891        Example:
3892            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3893            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3894
3895        Args:
3896            *expressions: the SQL code strings to parse.
3897                If a `Group` instance is passed, this is used as-is.
3898                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3899                If nothing is passed in then a group by is not applied to the expression
3900            append: if `True`, add to any existing expressions.
3901                Otherwise, this flattens all the `Group` expression into a single expression.
3902            dialect: the dialect used to parse the input expression.
3903            copy: if `False`, modify this expression instance in-place.
3904            opts: other options to use to parse the input expressions.
3905
3906        Returns:
3907            The modified Select expression.
3908        """
3909        if not expressions:
3910            return self if not copy else self.copy()
3911
3912        return _apply_child_list_builder(
3913            *expressions,
3914            instance=self,
3915            arg="group",
3916            append=append,
3917            copy=copy,
3918            prefix="GROUP BY",
3919            into=Group,
3920            dialect=dialect,
3921            **opts,
3922        )
3923
3924    def sort_by(
3925        self,
3926        *expressions: t.Optional[ExpOrStr],
3927        append: bool = True,
3928        dialect: DialectType = None,
3929        copy: bool = True,
3930        **opts,
3931    ) -> Select:
3932        """
3933        Set the SORT BY expression.
3934
3935        Example:
3936            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3937            'SELECT x FROM tbl SORT BY x DESC'
3938
3939        Args:
3940            *expressions: the SQL code strings to parse.
3941                If a `Group` instance is passed, this is used as-is.
3942                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3943            append: if `True`, add to any existing expressions.
3944                Otherwise, this flattens all the `Order` expression into a single expression.
3945            dialect: the dialect used to parse the input expression.
3946            copy: if `False`, modify this expression instance in-place.
3947            opts: other options to use to parse the input expressions.
3948
3949        Returns:
3950            The modified Select expression.
3951        """
3952        return _apply_child_list_builder(
3953            *expressions,
3954            instance=self,
3955            arg="sort",
3956            append=append,
3957            copy=copy,
3958            prefix="SORT BY",
3959            into=Sort,
3960            dialect=dialect,
3961            **opts,
3962        )
3963
3964    def cluster_by(
3965        self,
3966        *expressions: t.Optional[ExpOrStr],
3967        append: bool = True,
3968        dialect: DialectType = None,
3969        copy: bool = True,
3970        **opts,
3971    ) -> Select:
3972        """
3973        Set the CLUSTER BY expression.
3974
3975        Example:
3976            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3977            'SELECT x FROM tbl CLUSTER BY x DESC'
3978
3979        Args:
3980            *expressions: the SQL code strings to parse.
3981                If a `Group` instance is passed, this is used as-is.
3982                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3983            append: if `True`, add to any existing expressions.
3984                Otherwise, this flattens all the `Order` expression into a single expression.
3985            dialect: the dialect used to parse the input expression.
3986            copy: if `False`, modify this expression instance in-place.
3987            opts: other options to use to parse the input expressions.
3988
3989        Returns:
3990            The modified Select expression.
3991        """
3992        return _apply_child_list_builder(
3993            *expressions,
3994            instance=self,
3995            arg="cluster",
3996            append=append,
3997            copy=copy,
3998            prefix="CLUSTER BY",
3999            into=Cluster,
4000            dialect=dialect,
4001            **opts,
4002        )
4003
4004    def select(
4005        self,
4006        *expressions: t.Optional[ExpOrStr],
4007        append: bool = True,
4008        dialect: DialectType = None,
4009        copy: bool = True,
4010        **opts,
4011    ) -> Select:
4012        return _apply_list_builder(
4013            *expressions,
4014            instance=self,
4015            arg="expressions",
4016            append=append,
4017            dialect=dialect,
4018            into=Expression,
4019            copy=copy,
4020            **opts,
4021        )
4022
4023    def lateral(
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 LATERAL expressions.
4033
4034        Example:
4035            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
4036            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
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            append: if `True`, add to any existing expressions.
4042                Otherwise, this resets the expressions.
4043            dialect: the dialect used to parse the input expressions.
4044            copy: if `False`, modify this expression instance in-place.
4045            opts: other options to use to parse the input expressions.
4046
4047        Returns:
4048            The modified Select expression.
4049        """
4050        return _apply_list_builder(
4051            *expressions,
4052            instance=self,
4053            arg="laterals",
4054            append=append,
4055            into=Lateral,
4056            prefix="LATERAL VIEW",
4057            dialect=dialect,
4058            copy=copy,
4059            **opts,
4060        )
4061
4062    def join(
4063        self,
4064        expression: ExpOrStr,
4065        on: t.Optional[ExpOrStr] = None,
4066        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4067        append: bool = True,
4068        join_type: t.Optional[str] = None,
4069        join_alias: t.Optional[Identifier | str] = None,
4070        dialect: DialectType = None,
4071        copy: bool = True,
4072        **opts,
4073    ) -> Select:
4074        """
4075        Append to or set the JOIN expressions.
4076
4077        Example:
4078            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4079            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4080
4081            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4082            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4083
4084            Use `join_type` to change the type of join:
4085
4086            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4087            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4088
4089        Args:
4090            expression: the SQL code string to parse.
4091                If an `Expression` instance is passed, it will be used as-is.
4092            on: optionally specify the join "on" criteria as a SQL string.
4093                If an `Expression` instance is passed, it will be used as-is.
4094            using: optionally specify the join "using" criteria as a SQL string.
4095                If an `Expression` instance is passed, it will be used as-is.
4096            append: if `True`, add to any existing expressions.
4097                Otherwise, this resets the expressions.
4098            join_type: if set, alter the parsed join type.
4099            join_alias: an optional alias for the joined source.
4100            dialect: the dialect used to parse the input expressions.
4101            copy: if `False`, modify this expression instance in-place.
4102            opts: other options to use to parse the input expressions.
4103
4104        Returns:
4105            Select: the modified expression.
4106        """
4107        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4108
4109        try:
4110            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4111        except ParseError:
4112            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4113
4114        join = expression if isinstance(expression, Join) else Join(this=expression)
4115
4116        if isinstance(join.this, Select):
4117            join.this.replace(join.this.subquery())
4118
4119        if join_type:
4120            method: t.Optional[Token]
4121            side: t.Optional[Token]
4122            kind: t.Optional[Token]
4123
4124            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4125
4126            if method:
4127                join.set("method", method.text)
4128            if side:
4129                join.set("side", side.text)
4130            if kind:
4131                join.set("kind", kind.text)
4132
4133        if on:
4134            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4135            join.set("on", on)
4136
4137        if using:
4138            join = _apply_list_builder(
4139                *ensure_list(using),
4140                instance=join,
4141                arg="using",
4142                append=append,
4143                copy=copy,
4144                into=Identifier,
4145                **opts,
4146            )
4147
4148        if join_alias:
4149            join.set("this", alias_(join.this, join_alias, table=True))
4150
4151        return _apply_list_builder(
4152            join,
4153            instance=self,
4154            arg="joins",
4155            append=append,
4156            copy=copy,
4157            **opts,
4158        )
4159
4160    def having(
4161        self,
4162        *expressions: t.Optional[ExpOrStr],
4163        append: bool = True,
4164        dialect: DialectType = None,
4165        copy: bool = True,
4166        **opts,
4167    ) -> Select:
4168        """
4169        Append to or set the HAVING expressions.
4170
4171        Example:
4172            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4173            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4174
4175        Args:
4176            *expressions: the SQL code strings to parse.
4177                If an `Expression` instance is passed, it will be used as-is.
4178                Multiple expressions are combined with an AND operator.
4179            append: if `True`, AND the new expressions to any existing expression.
4180                Otherwise, this resets the expression.
4181            dialect: the dialect used to parse the input expressions.
4182            copy: if `False`, modify this expression instance in-place.
4183            opts: other options to use to parse the input expressions.
4184
4185        Returns:
4186            The modified Select expression.
4187        """
4188        return _apply_conjunction_builder(
4189            *expressions,
4190            instance=self,
4191            arg="having",
4192            append=append,
4193            into=Having,
4194            dialect=dialect,
4195            copy=copy,
4196            **opts,
4197        )
4198
4199    def window(
4200        self,
4201        *expressions: t.Optional[ExpOrStr],
4202        append: bool = True,
4203        dialect: DialectType = None,
4204        copy: bool = True,
4205        **opts,
4206    ) -> Select:
4207        return _apply_list_builder(
4208            *expressions,
4209            instance=self,
4210            arg="windows",
4211            append=append,
4212            into=Window,
4213            dialect=dialect,
4214            copy=copy,
4215            **opts,
4216        )
4217
4218    def qualify(
4219        self,
4220        *expressions: t.Optional[ExpOrStr],
4221        append: bool = True,
4222        dialect: DialectType = None,
4223        copy: bool = True,
4224        **opts,
4225    ) -> Select:
4226        return _apply_conjunction_builder(
4227            *expressions,
4228            instance=self,
4229            arg="qualify",
4230            append=append,
4231            into=Qualify,
4232            dialect=dialect,
4233            copy=copy,
4234            **opts,
4235        )
4236
4237    def distinct(
4238        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4239    ) -> Select:
4240        """
4241        Set the OFFSET expression.
4242
4243        Example:
4244            >>> Select().from_("tbl").select("x").distinct().sql()
4245            'SELECT DISTINCT x FROM tbl'
4246
4247        Args:
4248            ons: the expressions to distinct on
4249            distinct: whether the Select should be distinct
4250            copy: if `False`, modify this expression instance in-place.
4251
4252        Returns:
4253            Select: the modified expression.
4254        """
4255        instance = maybe_copy(self, copy)
4256        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4257        instance.set("distinct", Distinct(on=on) if distinct else None)
4258        return instance
4259
4260    def ctas(
4261        self,
4262        table: ExpOrStr,
4263        properties: t.Optional[t.Dict] = None,
4264        dialect: DialectType = None,
4265        copy: bool = True,
4266        **opts,
4267    ) -> Create:
4268        """
4269        Convert this expression to a CREATE TABLE AS statement.
4270
4271        Example:
4272            >>> Select().select("*").from_("tbl").ctas("x").sql()
4273            'CREATE TABLE x AS SELECT * FROM tbl'
4274
4275        Args:
4276            table: the SQL code string to parse as the table name.
4277                If another `Expression` instance is passed, it will be used as-is.
4278            properties: an optional mapping of table properties
4279            dialect: the dialect used to parse the input table.
4280            copy: if `False`, modify this expression instance in-place.
4281            opts: other options to use to parse the input table.
4282
4283        Returns:
4284            The new Create expression.
4285        """
4286        instance = maybe_copy(self, copy)
4287        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4288
4289        properties_expression = None
4290        if properties:
4291            properties_expression = Properties.from_dict(properties)
4292
4293        return Create(
4294            this=table_expression,
4295            kind="TABLE",
4296            expression=instance,
4297            properties=properties_expression,
4298        )
4299
4300    def lock(self, update: bool = True, copy: bool = True) -> Select:
4301        """
4302        Set the locking read mode for this expression.
4303
4304        Examples:
4305            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4306            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4307
4308            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4309            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4310
4311        Args:
4312            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4313            copy: if `False`, modify this expression instance in-place.
4314
4315        Returns:
4316            The modified expression.
4317        """
4318        inst = maybe_copy(self, copy)
4319        inst.set("locks", [Lock(update=update)])
4320
4321        return inst
4322
4323    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4324        """
4325        Set hints for this expression.
4326
4327        Examples:
4328            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4329            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4330
4331        Args:
4332            hints: The SQL code strings to parse as the hints.
4333                If an `Expression` instance is passed, it will be used as-is.
4334            dialect: The dialect used to parse the hints.
4335            copy: If `False`, modify this expression instance in-place.
4336
4337        Returns:
4338            The modified expression.
4339        """
4340        inst = maybe_copy(self, copy)
4341        inst.set(
4342            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4343        )
4344
4345        return inst
4346
4347    @property
4348    def named_selects(self) -> t.List[str]:
4349        selects = []
4350
4351        for e in self.expressions:
4352            if e.alias_or_name:
4353                selects.append(e.output_name)
4354            elif isinstance(e, Aliases):
4355                selects.extend([a.name for a in e.aliases])
4356        return selects
4357
4358    @property
4359    def is_star(self) -> bool:
4360        return any(expression.is_star for expression in self.expressions)
4361
4362    @property
4363    def selects(self) -> t.List[Expression]:
4364        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:
3848    def from_(
3849        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3850    ) -> Select:
3851        """
3852        Set the FROM expression.
3853
3854        Example:
3855            >>> Select().from_("tbl").select("x").sql()
3856            'SELECT x FROM tbl'
3857
3858        Args:
3859            expression : the SQL code strings to parse.
3860                If a `From` instance is passed, this is used as-is.
3861                If another `Expression` instance is passed, it will be wrapped in a `From`.
3862            dialect: the dialect used to parse the input expression.
3863            copy: if `False`, modify this expression instance in-place.
3864            opts: other options to use to parse the input expressions.
3865
3866        Returns:
3867            The modified Select expression.
3868        """
3869        return _apply_builder(
3870            expression=expression,
3871            instance=self,
3872            arg="from",
3873            into=From,
3874            prefix="FROM",
3875            dialect=dialect,
3876            copy=copy,
3877            **opts,
3878        )

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:
3880    def group_by(
3881        self,
3882        *expressions: t.Optional[ExpOrStr],
3883        append: bool = True,
3884        dialect: DialectType = None,
3885        copy: bool = True,
3886        **opts,
3887    ) -> Select:
3888        """
3889        Set the GROUP BY expression.
3890
3891        Example:
3892            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3893            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3894
3895        Args:
3896            *expressions: the SQL code strings to parse.
3897                If a `Group` instance is passed, this is used as-is.
3898                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3899                If nothing is passed in then a group by is not applied to the expression
3900            append: if `True`, add to any existing expressions.
3901                Otherwise, this flattens all the `Group` expression into a single expression.
3902            dialect: the dialect used to parse the input expression.
3903            copy: if `False`, modify this expression instance in-place.
3904            opts: other options to use to parse the input expressions.
3905
3906        Returns:
3907            The modified Select expression.
3908        """
3909        if not expressions:
3910            return self if not copy else self.copy()
3911
3912        return _apply_child_list_builder(
3913            *expressions,
3914            instance=self,
3915            arg="group",
3916            append=append,
3917            copy=copy,
3918            prefix="GROUP BY",
3919            into=Group,
3920            dialect=dialect,
3921            **opts,
3922        )

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:
3924    def sort_by(
3925        self,
3926        *expressions: t.Optional[ExpOrStr],
3927        append: bool = True,
3928        dialect: DialectType = None,
3929        copy: bool = True,
3930        **opts,
3931    ) -> Select:
3932        """
3933        Set the SORT BY expression.
3934
3935        Example:
3936            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3937            'SELECT x FROM tbl SORT BY x DESC'
3938
3939        Args:
3940            *expressions: the SQL code strings to parse.
3941                If a `Group` instance is passed, this is used as-is.
3942                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3943            append: if `True`, add to any existing expressions.
3944                Otherwise, this flattens all the `Order` expression into a single expression.
3945            dialect: the dialect used to parse the input expression.
3946            copy: if `False`, modify this expression instance in-place.
3947            opts: other options to use to parse the input expressions.
3948
3949        Returns:
3950            The modified Select expression.
3951        """
3952        return _apply_child_list_builder(
3953            *expressions,
3954            instance=self,
3955            arg="sort",
3956            append=append,
3957            copy=copy,
3958            prefix="SORT BY",
3959            into=Sort,
3960            dialect=dialect,
3961            **opts,
3962        )

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:
3964    def cluster_by(
3965        self,
3966        *expressions: t.Optional[ExpOrStr],
3967        append: bool = True,
3968        dialect: DialectType = None,
3969        copy: bool = True,
3970        **opts,
3971    ) -> Select:
3972        """
3973        Set the CLUSTER BY expression.
3974
3975        Example:
3976            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3977            'SELECT x FROM tbl CLUSTER BY x DESC'
3978
3979        Args:
3980            *expressions: the SQL code strings to parse.
3981                If a `Group` instance is passed, this is used as-is.
3982                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3983            append: if `True`, add to any existing expressions.
3984                Otherwise, this flattens all the `Order` expression into a single expression.
3985            dialect: the dialect used to parse the input expression.
3986            copy: if `False`, modify this expression instance in-place.
3987            opts: other options to use to parse the input expressions.
3988
3989        Returns:
3990            The modified Select expression.
3991        """
3992        return _apply_child_list_builder(
3993            *expressions,
3994            instance=self,
3995            arg="cluster",
3996            append=append,
3997            copy=copy,
3998            prefix="CLUSTER BY",
3999            into=Cluster,
4000            dialect=dialect,
4001            **opts,
4002        )

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:
4004    def select(
4005        self,
4006        *expressions: t.Optional[ExpOrStr],
4007        append: bool = True,
4008        dialect: DialectType = None,
4009        copy: bool = True,
4010        **opts,
4011    ) -> Select:
4012        return _apply_list_builder(
4013            *expressions,
4014            instance=self,
4015            arg="expressions",
4016            append=append,
4017            dialect=dialect,
4018            into=Expression,
4019            copy=copy,
4020            **opts,
4021        )

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:
4023    def lateral(
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 LATERAL expressions.
4033
4034        Example:
4035            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
4036            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
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            append: if `True`, add to any existing expressions.
4042                Otherwise, this resets the expressions.
4043            dialect: the dialect used to parse the input expressions.
4044            copy: if `False`, modify this expression instance in-place.
4045            opts: other options to use to parse the input expressions.
4046
4047        Returns:
4048            The modified Select expression.
4049        """
4050        return _apply_list_builder(
4051            *expressions,
4052            instance=self,
4053            arg="laterals",
4054            append=append,
4055            into=Lateral,
4056            prefix="LATERAL VIEW",
4057            dialect=dialect,
4058            copy=copy,
4059            **opts,
4060        )

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:
4062    def join(
4063        self,
4064        expression: ExpOrStr,
4065        on: t.Optional[ExpOrStr] = None,
4066        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4067        append: bool = True,
4068        join_type: t.Optional[str] = None,
4069        join_alias: t.Optional[Identifier | str] = None,
4070        dialect: DialectType = None,
4071        copy: bool = True,
4072        **opts,
4073    ) -> Select:
4074        """
4075        Append to or set the JOIN expressions.
4076
4077        Example:
4078            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4079            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4080
4081            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4082            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4083
4084            Use `join_type` to change the type of join:
4085
4086            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4087            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4088
4089        Args:
4090            expression: the SQL code string to parse.
4091                If an `Expression` instance is passed, it will be used as-is.
4092            on: optionally specify the join "on" criteria as a SQL string.
4093                If an `Expression` instance is passed, it will be used as-is.
4094            using: optionally specify the join "using" criteria as a SQL string.
4095                If an `Expression` instance is passed, it will be used as-is.
4096            append: if `True`, add to any existing expressions.
4097                Otherwise, this resets the expressions.
4098            join_type: if set, alter the parsed join type.
4099            join_alias: an optional alias for the joined source.
4100            dialect: the dialect used to parse the input expressions.
4101            copy: if `False`, modify this expression instance in-place.
4102            opts: other options to use to parse the input expressions.
4103
4104        Returns:
4105            Select: the modified expression.
4106        """
4107        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4108
4109        try:
4110            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4111        except ParseError:
4112            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4113
4114        join = expression if isinstance(expression, Join) else Join(this=expression)
4115
4116        if isinstance(join.this, Select):
4117            join.this.replace(join.this.subquery())
4118
4119        if join_type:
4120            method: t.Optional[Token]
4121            side: t.Optional[Token]
4122            kind: t.Optional[Token]
4123
4124            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4125
4126            if method:
4127                join.set("method", method.text)
4128            if side:
4129                join.set("side", side.text)
4130            if kind:
4131                join.set("kind", kind.text)
4132
4133        if on:
4134            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4135            join.set("on", on)
4136
4137        if using:
4138            join = _apply_list_builder(
4139                *ensure_list(using),
4140                instance=join,
4141                arg="using",
4142                append=append,
4143                copy=copy,
4144                into=Identifier,
4145                **opts,
4146            )
4147
4148        if join_alias:
4149            join.set("this", alias_(join.this, join_alias, table=True))
4150
4151        return _apply_list_builder(
4152            join,
4153            instance=self,
4154            arg="joins",
4155            append=append,
4156            copy=copy,
4157            **opts,
4158        )

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 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:
4160    def having(
4161        self,
4162        *expressions: t.Optional[ExpOrStr],
4163        append: bool = True,
4164        dialect: DialectType = None,
4165        copy: bool = True,
4166        **opts,
4167    ) -> Select:
4168        """
4169        Append to or set the HAVING expressions.
4170
4171        Example:
4172            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4173            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4174
4175        Args:
4176            *expressions: the SQL code strings to parse.
4177                If an `Expression` instance is passed, it will be used as-is.
4178                Multiple expressions are combined with an AND operator.
4179            append: if `True`, AND the new expressions to any existing expression.
4180                Otherwise, this resets the expression.
4181            dialect: the dialect used to parse the input expressions.
4182            copy: if `False`, modify this expression instance in-place.
4183            opts: other options to use to parse the input expressions.
4184
4185        Returns:
4186            The modified Select expression.
4187        """
4188        return _apply_conjunction_builder(
4189            *expressions,
4190            instance=self,
4191            arg="having",
4192            append=append,
4193            into=Having,
4194            dialect=dialect,
4195            copy=copy,
4196            **opts,
4197        )

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:
4199    def window(
4200        self,
4201        *expressions: t.Optional[ExpOrStr],
4202        append: bool = True,
4203        dialect: DialectType = None,
4204        copy: bool = True,
4205        **opts,
4206    ) -> Select:
4207        return _apply_list_builder(
4208            *expressions,
4209            instance=self,
4210            arg="windows",
4211            append=append,
4212            into=Window,
4213            dialect=dialect,
4214            copy=copy,
4215            **opts,
4216        )
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:
4218    def qualify(
4219        self,
4220        *expressions: t.Optional[ExpOrStr],
4221        append: bool = True,
4222        dialect: DialectType = None,
4223        copy: bool = True,
4224        **opts,
4225    ) -> Select:
4226        return _apply_conjunction_builder(
4227            *expressions,
4228            instance=self,
4229            arg="qualify",
4230            append=append,
4231            into=Qualify,
4232            dialect=dialect,
4233            copy=copy,
4234            **opts,
4235        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4237    def distinct(
4238        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4239    ) -> Select:
4240        """
4241        Set the OFFSET expression.
4242
4243        Example:
4244            >>> Select().from_("tbl").select("x").distinct().sql()
4245            'SELECT DISTINCT x FROM tbl'
4246
4247        Args:
4248            ons: the expressions to distinct on
4249            distinct: whether the Select should be distinct
4250            copy: if `False`, modify this expression instance in-place.
4251
4252        Returns:
4253            Select: the modified expression.
4254        """
4255        instance = maybe_copy(self, copy)
4256        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4257        instance.set("distinct", Distinct(on=on) if distinct else None)
4258        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:
4260    def ctas(
4261        self,
4262        table: ExpOrStr,
4263        properties: t.Optional[t.Dict] = None,
4264        dialect: DialectType = None,
4265        copy: bool = True,
4266        **opts,
4267    ) -> Create:
4268        """
4269        Convert this expression to a CREATE TABLE AS statement.
4270
4271        Example:
4272            >>> Select().select("*").from_("tbl").ctas("x").sql()
4273            'CREATE TABLE x AS SELECT * FROM tbl'
4274
4275        Args:
4276            table: the SQL code string to parse as the table name.
4277                If another `Expression` instance is passed, it will be used as-is.
4278            properties: an optional mapping of table properties
4279            dialect: the dialect used to parse the input table.
4280            copy: if `False`, modify this expression instance in-place.
4281            opts: other options to use to parse the input table.
4282
4283        Returns:
4284            The new Create expression.
4285        """
4286        instance = maybe_copy(self, copy)
4287        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4288
4289        properties_expression = None
4290        if properties:
4291            properties_expression = Properties.from_dict(properties)
4292
4293        return Create(
4294            this=table_expression,
4295            kind="TABLE",
4296            expression=instance,
4297            properties=properties_expression,
4298        )

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:
4300    def lock(self, update: bool = True, copy: bool = True) -> Select:
4301        """
4302        Set the locking read mode for this expression.
4303
4304        Examples:
4305            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4306            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4307
4308            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4309            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4310
4311        Args:
4312            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4313            copy: if `False`, modify this expression instance in-place.
4314
4315        Returns:
4316            The modified expression.
4317        """
4318        inst = maybe_copy(self, copy)
4319        inst.set("locks", [Lock(update=update)])
4320
4321        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:
4323    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4324        """
4325        Set hints for this expression.
4326
4327        Examples:
4328            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4329            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4330
4331        Args:
4332            hints: The SQL code strings to parse as the hints.
4333                If an `Expression` instance is passed, it will be used as-is.
4334            dialect: The dialect used to parse the hints.
4335            copy: If `False`, modify this expression instance in-place.
4336
4337        Returns:
4338            The modified expression.
4339        """
4340        inst = maybe_copy(self, copy)
4341        inst.set(
4342            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4343        )
4344
4345        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]
4347    @property
4348    def named_selects(self) -> t.List[str]:
4349        selects = []
4350
4351        for e in self.expressions:
4352            if e.alias_or_name:
4353                selects.append(e.output_name)
4354            elif isinstance(e, Aliases):
4355                selects.extend([a.name for a in e.aliases])
4356        return selects

Returns the output names of the query's projections.

is_star: bool
4358    @property
4359    def is_star(self) -> bool:
4360        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4362    @property
4363    def selects(self) -> t.List[Expression]:
4364        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4370class Subquery(DerivedTable, Query):
4371    arg_types = {
4372        "this": True,
4373        "alias": False,
4374        "with": False,
4375        **QUERY_MODIFIERS,
4376    }
4377
4378    def unnest(self):
4379        """Returns the first non subquery."""
4380        expression = self
4381        while isinstance(expression, Subquery):
4382            expression = expression.this
4383        return expression
4384
4385    def unwrap(self) -> Subquery:
4386        expression = self
4387        while expression.same_parent and expression.is_wrapper:
4388            expression = t.cast(Subquery, expression.parent)
4389        return expression
4390
4391    def select(
4392        self,
4393        *expressions: t.Optional[ExpOrStr],
4394        append: bool = True,
4395        dialect: DialectType = None,
4396        copy: bool = True,
4397        **opts,
4398    ) -> Subquery:
4399        this = maybe_copy(self, copy)
4400        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4401        return this
4402
4403    @property
4404    def is_wrapper(self) -> bool:
4405        """
4406        Whether this Subquery acts as a simple wrapper around another expression.
4407
4408        SELECT * FROM (((SELECT * FROM t)))
4409                      ^
4410                      This corresponds to a "wrapper" Subquery node
4411        """
4412        return all(v is None for k, v in self.args.items() if k != "this")
4413
4414    @property
4415    def is_star(self) -> bool:
4416        return self.this.is_star
4417
4418    @property
4419    def output_name(self) -> str:
4420        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):
4378    def unnest(self):
4379        """Returns the first non subquery."""
4380        expression = self
4381        while isinstance(expression, Subquery):
4382            expression = expression.this
4383        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4385    def unwrap(self) -> Subquery:
4386        expression = self
4387        while expression.same_parent and expression.is_wrapper:
4388            expression = t.cast(Subquery, expression.parent)
4389        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:
4391    def select(
4392        self,
4393        *expressions: t.Optional[ExpOrStr],
4394        append: bool = True,
4395        dialect: DialectType = None,
4396        copy: bool = True,
4397        **opts,
4398    ) -> Subquery:
4399        this = maybe_copy(self, copy)
4400        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4401        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
4403    @property
4404    def is_wrapper(self) -> bool:
4405        """
4406        Whether this Subquery acts as a simple wrapper around another expression.
4407
4408        SELECT * FROM (((SELECT * FROM t)))
4409                      ^
4410                      This corresponds to a "wrapper" Subquery node
4411        """
4412        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
4414    @property
4415    def is_star(self) -> bool:
4416        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4418    @property
4419    def output_name(self) -> str:
4420        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):
4423class TableSample(Expression):
4424    arg_types = {
4425        "expressions": False,
4426        "method": False,
4427        "bucket_numerator": False,
4428        "bucket_denominator": False,
4429        "bucket_field": False,
4430        "percent": False,
4431        "rows": False,
4432        "size": False,
4433        "seed": False,
4434    }
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):
4437class Tag(Expression):
4438    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4439
4440    arg_types = {
4441        "this": False,
4442        "prefix": False,
4443        "postfix": False,
4444    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4449class Pivot(Expression):
4450    arg_types = {
4451        "this": False,
4452        "alias": False,
4453        "expressions": False,
4454        "fields": False,
4455        "unpivot": False,
4456        "using": False,
4457        "group": False,
4458        "columns": False,
4459        "include_nulls": False,
4460        "default_on_null": False,
4461        "into": False,
4462    }
4463
4464    @property
4465    def unpivot(self) -> bool:
4466        return bool(self.args.get("unpivot"))
4467
4468    @property
4469    def fields(self) -> t.List[Expression]:
4470        return self.args.get("fields", [])
arg_types = {'this': False, 'alias': False, 'expressions': False, 'fields': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4464    @property
4465    def unpivot(self) -> bool:
4466        return bool(self.args.get("unpivot"))
fields: List[Expression]
4468    @property
4469    def fields(self) -> t.List[Expression]:
4470        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4475class UnpivotColumns(Expression):
4476    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4479class Window(Condition):
4480    arg_types = {
4481        "this": True,
4482        "partition_by": False,
4483        "order": False,
4484        "spec": False,
4485        "alias": False,
4486        "over": False,
4487        "first": False,
4488    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4491class WindowSpec(Expression):
4492    arg_types = {
4493        "kind": False,
4494        "start": False,
4495        "start_side": False,
4496        "end": False,
4497        "end_side": False,
4498        "exclude": False,
4499    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4502class PreWhere(Expression):
4503    pass
key = 'prewhere'
class Where(Expression):
4506class Where(Expression):
4507    pass
key = 'where'
class Star(Expression):
4510class Star(Expression):
4511    arg_types = {"except": False, "replace": False, "rename": False}
4512
4513    @property
4514    def name(self) -> str:
4515        return "*"
4516
4517    @property
4518    def output_name(self) -> str:
4519        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4513    @property
4514    def name(self) -> str:
4515        return "*"
output_name: str
4517    @property
4518    def output_name(self) -> str:
4519        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):
4522class Parameter(Condition):
4523    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4526class SessionParameter(Condition):
4527    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4532class Placeholder(Condition):
4533    arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
4534
4535    @property
4536    def name(self) -> str:
4537        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False, 'jdbc': False}
name: str
4535    @property
4536    def name(self) -> str:
4537        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4540class Null(Condition):
4541    arg_types: t.Dict[str, t.Any] = {}
4542
4543    @property
4544    def name(self) -> str:
4545        return "NULL"
4546
4547    def to_py(self) -> Lit[None]:
4548        return None
arg_types: Dict[str, Any] = {}
name: str
4543    @property
4544    def name(self) -> str:
4545        return "NULL"
def to_py(self) -> Literal[None]:
4547    def to_py(self) -> Lit[None]:
4548        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4551class Boolean(Condition):
4552    def to_py(self) -> bool:
4553        return self.this
def to_py(self) -> bool:
4552    def to_py(self) -> bool:
4553        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4556class DataTypeParam(Expression):
4557    arg_types = {"this": True, "expression": False}
4558
4559    @property
4560    def name(self) -> str:
4561        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4559    @property
4560    def name(self) -> str:
4561        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4566class DataType(Expression):
4567    arg_types = {
4568        "this": True,
4569        "expressions": False,
4570        "nested": False,
4571        "values": False,
4572        "prefix": False,
4573        "kind": False,
4574        "nullable": False,
4575    }
4576
4577    class Type(AutoName):
4578        ARRAY = auto()
4579        AGGREGATEFUNCTION = auto()
4580        SIMPLEAGGREGATEFUNCTION = auto()
4581        BIGDECIMAL = auto()
4582        BIGINT = auto()
4583        BIGSERIAL = auto()
4584        BINARY = auto()
4585        BIT = auto()
4586        BLOB = auto()
4587        BOOLEAN = auto()
4588        BPCHAR = auto()
4589        CHAR = auto()
4590        DATE = auto()
4591        DATE32 = auto()
4592        DATEMULTIRANGE = auto()
4593        DATERANGE = auto()
4594        DATETIME = auto()
4595        DATETIME2 = auto()
4596        DATETIME64 = auto()
4597        DECIMAL = auto()
4598        DECIMAL32 = auto()
4599        DECIMAL64 = auto()
4600        DECIMAL128 = auto()
4601        DECIMAL256 = auto()
4602        DOUBLE = auto()
4603        DYNAMIC = auto()
4604        ENUM = auto()
4605        ENUM8 = auto()
4606        ENUM16 = auto()
4607        FIXEDSTRING = auto()
4608        FLOAT = auto()
4609        GEOGRAPHY = auto()
4610        GEOGRAPHYPOINT = auto()
4611        GEOMETRY = auto()
4612        POINT = auto()
4613        RING = auto()
4614        LINESTRING = auto()
4615        MULTILINESTRING = auto()
4616        POLYGON = auto()
4617        MULTIPOLYGON = auto()
4618        HLLSKETCH = auto()
4619        HSTORE = auto()
4620        IMAGE = auto()
4621        INET = auto()
4622        INT = auto()
4623        INT128 = auto()
4624        INT256 = auto()
4625        INT4MULTIRANGE = auto()
4626        INT4RANGE = auto()
4627        INT8MULTIRANGE = auto()
4628        INT8RANGE = auto()
4629        INTERVAL = auto()
4630        IPADDRESS = auto()
4631        IPPREFIX = auto()
4632        IPV4 = auto()
4633        IPV6 = auto()
4634        JSON = auto()
4635        JSONB = auto()
4636        LIST = auto()
4637        LONGBLOB = auto()
4638        LONGTEXT = auto()
4639        LOWCARDINALITY = auto()
4640        MAP = auto()
4641        MEDIUMBLOB = auto()
4642        MEDIUMINT = auto()
4643        MEDIUMTEXT = auto()
4644        MONEY = auto()
4645        NAME = auto()
4646        NCHAR = auto()
4647        NESTED = auto()
4648        NOTHING = auto()
4649        NULL = auto()
4650        NUMMULTIRANGE = auto()
4651        NUMRANGE = auto()
4652        NVARCHAR = auto()
4653        OBJECT = auto()
4654        RANGE = auto()
4655        ROWVERSION = auto()
4656        SERIAL = auto()
4657        SET = auto()
4658        SMALLDATETIME = auto()
4659        SMALLINT = auto()
4660        SMALLMONEY = auto()
4661        SMALLSERIAL = auto()
4662        STRUCT = auto()
4663        SUPER = auto()
4664        TEXT = auto()
4665        TINYBLOB = auto()
4666        TINYTEXT = auto()
4667        TIME = auto()
4668        TIMETZ = auto()
4669        TIMESTAMP = auto()
4670        TIMESTAMPNTZ = auto()
4671        TIMESTAMPLTZ = auto()
4672        TIMESTAMPTZ = auto()
4673        TIMESTAMP_S = auto()
4674        TIMESTAMP_MS = auto()
4675        TIMESTAMP_NS = auto()
4676        TINYINT = auto()
4677        TSMULTIRANGE = auto()
4678        TSRANGE = auto()
4679        TSTZMULTIRANGE = auto()
4680        TSTZRANGE = auto()
4681        UBIGINT = auto()
4682        UINT = auto()
4683        UINT128 = auto()
4684        UINT256 = auto()
4685        UMEDIUMINT = auto()
4686        UDECIMAL = auto()
4687        UDOUBLE = auto()
4688        UNION = auto()
4689        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4690        USERDEFINED = "USER-DEFINED"
4691        USMALLINT = auto()
4692        UTINYINT = auto()
4693        UUID = auto()
4694        VARBINARY = auto()
4695        VARCHAR = auto()
4696        VARIANT = auto()
4697        VECTOR = auto()
4698        XML = auto()
4699        YEAR = auto()
4700        TDIGEST = auto()
4701
4702    STRUCT_TYPES = {
4703        Type.NESTED,
4704        Type.OBJECT,
4705        Type.STRUCT,
4706        Type.UNION,
4707    }
4708
4709    ARRAY_TYPES = {
4710        Type.ARRAY,
4711        Type.LIST,
4712    }
4713
4714    NESTED_TYPES = {
4715        *STRUCT_TYPES,
4716        *ARRAY_TYPES,
4717        Type.MAP,
4718    }
4719
4720    TEXT_TYPES = {
4721        Type.CHAR,
4722        Type.NCHAR,
4723        Type.NVARCHAR,
4724        Type.TEXT,
4725        Type.VARCHAR,
4726        Type.NAME,
4727    }
4728
4729    SIGNED_INTEGER_TYPES = {
4730        Type.BIGINT,
4731        Type.INT,
4732        Type.INT128,
4733        Type.INT256,
4734        Type.MEDIUMINT,
4735        Type.SMALLINT,
4736        Type.TINYINT,
4737    }
4738
4739    UNSIGNED_INTEGER_TYPES = {
4740        Type.UBIGINT,
4741        Type.UINT,
4742        Type.UINT128,
4743        Type.UINT256,
4744        Type.UMEDIUMINT,
4745        Type.USMALLINT,
4746        Type.UTINYINT,
4747    }
4748
4749    INTEGER_TYPES = {
4750        *SIGNED_INTEGER_TYPES,
4751        *UNSIGNED_INTEGER_TYPES,
4752        Type.BIT,
4753    }
4754
4755    FLOAT_TYPES = {
4756        Type.DOUBLE,
4757        Type.FLOAT,
4758    }
4759
4760    REAL_TYPES = {
4761        *FLOAT_TYPES,
4762        Type.BIGDECIMAL,
4763        Type.DECIMAL,
4764        Type.DECIMAL32,
4765        Type.DECIMAL64,
4766        Type.DECIMAL128,
4767        Type.DECIMAL256,
4768        Type.MONEY,
4769        Type.SMALLMONEY,
4770        Type.UDECIMAL,
4771        Type.UDOUBLE,
4772    }
4773
4774    NUMERIC_TYPES = {
4775        *INTEGER_TYPES,
4776        *REAL_TYPES,
4777    }
4778
4779    TEMPORAL_TYPES = {
4780        Type.DATE,
4781        Type.DATE32,
4782        Type.DATETIME,
4783        Type.DATETIME2,
4784        Type.DATETIME64,
4785        Type.SMALLDATETIME,
4786        Type.TIME,
4787        Type.TIMESTAMP,
4788        Type.TIMESTAMPNTZ,
4789        Type.TIMESTAMPLTZ,
4790        Type.TIMESTAMPTZ,
4791        Type.TIMESTAMP_MS,
4792        Type.TIMESTAMP_NS,
4793        Type.TIMESTAMP_S,
4794        Type.TIMETZ,
4795    }
4796
4797    @classmethod
4798    def build(
4799        cls,
4800        dtype: DATA_TYPE,
4801        dialect: DialectType = None,
4802        udt: bool = False,
4803        copy: bool = True,
4804        **kwargs,
4805    ) -> DataType:
4806        """
4807        Constructs a DataType object.
4808
4809        Args:
4810            dtype: the data type of interest.
4811            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4812            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4813                DataType, thus creating a user-defined type.
4814            copy: whether to copy the data type.
4815            kwargs: additional arguments to pass in the constructor of DataType.
4816
4817        Returns:
4818            The constructed DataType object.
4819        """
4820        from sqlglot import parse_one
4821
4822        if isinstance(dtype, str):
4823            if dtype.upper() == "UNKNOWN":
4824                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4825
4826            try:
4827                data_type_exp = parse_one(
4828                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4829                )
4830            except ParseError:
4831                if udt:
4832                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4833                raise
4834        elif isinstance(dtype, (Identifier, Dot)) and udt:
4835            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4836        elif isinstance(dtype, DataType.Type):
4837            data_type_exp = DataType(this=dtype)
4838        elif isinstance(dtype, DataType):
4839            return maybe_copy(dtype, copy)
4840        else:
4841            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4842
4843        return DataType(**{**data_type_exp.args, **kwargs})
4844
4845    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4846        """
4847        Checks whether this DataType matches one of the provided data types. Nested types or precision
4848        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4849
4850        Args:
4851            dtypes: the data types to compare this DataType to.
4852            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4853                If false, it means that NULLABLE<INT> is equivalent to INT.
4854
4855        Returns:
4856            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4857        """
4858        self_is_nullable = self.args.get("nullable")
4859        for dtype in dtypes:
4860            other_type = DataType.build(dtype, copy=False, udt=True)
4861            other_is_nullable = other_type.args.get("nullable")
4862            if (
4863                other_type.expressions
4864                or (check_nullable and (self_is_nullable or other_is_nullable))
4865                or self.this == DataType.Type.USERDEFINED
4866                or other_type.this == DataType.Type.USERDEFINED
4867            ):
4868                matches = self == other_type
4869            else:
4870                matches = self.this == other_type.this
4871
4872            if matches:
4873                return True
4874        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>, <Type.STRUCT: 'STRUCT'>, <Type.LIST: 'LIST'>, <Type.UNION: 'UNION'>}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.NAME: 'NAME'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>}
INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.BIT: 'BIT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.USMALLINT: 'USMALLINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.DECIMAL128: 'DECIMAL128'>, <Type.MONEY: 'MONEY'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.UINT128: 'UINT128'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT128: 'INT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UBIGINT: 'UBIGINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT: 'UINT'>, <Type.BIT: 'BIT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
TEMPORAL_TYPES = {<Type.DATETIME64: 'DATETIME64'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>}
@classmethod
def build( cls, dtype: Union[str, Identifier, Dot, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4797    @classmethod
4798    def build(
4799        cls,
4800        dtype: DATA_TYPE,
4801        dialect: DialectType = None,
4802        udt: bool = False,
4803        copy: bool = True,
4804        **kwargs,
4805    ) -> DataType:
4806        """
4807        Constructs a DataType object.
4808
4809        Args:
4810            dtype: the data type of interest.
4811            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4812            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4813                DataType, thus creating a user-defined type.
4814            copy: whether to copy the data type.
4815            kwargs: additional arguments to pass in the constructor of DataType.
4816
4817        Returns:
4818            The constructed DataType object.
4819        """
4820        from sqlglot import parse_one
4821
4822        if isinstance(dtype, str):
4823            if dtype.upper() == "UNKNOWN":
4824                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4825
4826            try:
4827                data_type_exp = parse_one(
4828                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4829                )
4830            except ParseError:
4831                if udt:
4832                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4833                raise
4834        elif isinstance(dtype, (Identifier, Dot)) and udt:
4835            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4836        elif isinstance(dtype, DataType.Type):
4837            data_type_exp = DataType(this=dtype)
4838        elif isinstance(dtype, DataType):
4839            return maybe_copy(dtype, copy)
4840        else:
4841            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4842
4843        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, Identifier, Dot, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4845    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4846        """
4847        Checks whether this DataType matches one of the provided data types. Nested types or precision
4848        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4849
4850        Args:
4851            dtypes: the data types to compare this DataType to.
4852            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4853                If false, it means that NULLABLE<INT> is equivalent to INT.
4854
4855        Returns:
4856            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4857        """
4858        self_is_nullable = self.args.get("nullable")
4859        for dtype in dtypes:
4860            other_type = DataType.build(dtype, copy=False, udt=True)
4861            other_is_nullable = other_type.args.get("nullable")
4862            if (
4863                other_type.expressions
4864                or (check_nullable and (self_is_nullable or other_is_nullable))
4865                or self.this == DataType.Type.USERDEFINED
4866                or other_type.this == DataType.Type.USERDEFINED
4867            ):
4868                matches = self == other_type
4869            else:
4870                matches = self.this == other_type.this
4871
4872            if matches:
4873                return True
4874        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):
4577    class Type(AutoName):
4578        ARRAY = auto()
4579        AGGREGATEFUNCTION = auto()
4580        SIMPLEAGGREGATEFUNCTION = auto()
4581        BIGDECIMAL = auto()
4582        BIGINT = auto()
4583        BIGSERIAL = auto()
4584        BINARY = auto()
4585        BIT = auto()
4586        BLOB = auto()
4587        BOOLEAN = auto()
4588        BPCHAR = auto()
4589        CHAR = auto()
4590        DATE = auto()
4591        DATE32 = auto()
4592        DATEMULTIRANGE = auto()
4593        DATERANGE = auto()
4594        DATETIME = auto()
4595        DATETIME2 = auto()
4596        DATETIME64 = auto()
4597        DECIMAL = auto()
4598        DECIMAL32 = auto()
4599        DECIMAL64 = auto()
4600        DECIMAL128 = auto()
4601        DECIMAL256 = auto()
4602        DOUBLE = auto()
4603        DYNAMIC = auto()
4604        ENUM = auto()
4605        ENUM8 = auto()
4606        ENUM16 = auto()
4607        FIXEDSTRING = auto()
4608        FLOAT = auto()
4609        GEOGRAPHY = auto()
4610        GEOGRAPHYPOINT = auto()
4611        GEOMETRY = auto()
4612        POINT = auto()
4613        RING = auto()
4614        LINESTRING = auto()
4615        MULTILINESTRING = auto()
4616        POLYGON = auto()
4617        MULTIPOLYGON = auto()
4618        HLLSKETCH = auto()
4619        HSTORE = auto()
4620        IMAGE = auto()
4621        INET = auto()
4622        INT = auto()
4623        INT128 = auto()
4624        INT256 = auto()
4625        INT4MULTIRANGE = auto()
4626        INT4RANGE = auto()
4627        INT8MULTIRANGE = auto()
4628        INT8RANGE = auto()
4629        INTERVAL = auto()
4630        IPADDRESS = auto()
4631        IPPREFIX = auto()
4632        IPV4 = auto()
4633        IPV6 = auto()
4634        JSON = auto()
4635        JSONB = auto()
4636        LIST = auto()
4637        LONGBLOB = auto()
4638        LONGTEXT = auto()
4639        LOWCARDINALITY = auto()
4640        MAP = auto()
4641        MEDIUMBLOB = auto()
4642        MEDIUMINT = auto()
4643        MEDIUMTEXT = auto()
4644        MONEY = auto()
4645        NAME = auto()
4646        NCHAR = auto()
4647        NESTED = auto()
4648        NOTHING = auto()
4649        NULL = auto()
4650        NUMMULTIRANGE = auto()
4651        NUMRANGE = auto()
4652        NVARCHAR = auto()
4653        OBJECT = auto()
4654        RANGE = auto()
4655        ROWVERSION = auto()
4656        SERIAL = auto()
4657        SET = auto()
4658        SMALLDATETIME = auto()
4659        SMALLINT = auto()
4660        SMALLMONEY = auto()
4661        SMALLSERIAL = auto()
4662        STRUCT = auto()
4663        SUPER = auto()
4664        TEXT = auto()
4665        TINYBLOB = auto()
4666        TINYTEXT = auto()
4667        TIME = auto()
4668        TIMETZ = auto()
4669        TIMESTAMP = auto()
4670        TIMESTAMPNTZ = auto()
4671        TIMESTAMPLTZ = auto()
4672        TIMESTAMPTZ = auto()
4673        TIMESTAMP_S = auto()
4674        TIMESTAMP_MS = auto()
4675        TIMESTAMP_NS = auto()
4676        TINYINT = auto()
4677        TSMULTIRANGE = auto()
4678        TSRANGE = auto()
4679        TSTZMULTIRANGE = auto()
4680        TSTZRANGE = auto()
4681        UBIGINT = auto()
4682        UINT = auto()
4683        UINT128 = auto()
4684        UINT256 = auto()
4685        UMEDIUMINT = auto()
4686        UDECIMAL = auto()
4687        UDOUBLE = auto()
4688        UNION = auto()
4689        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4690        USERDEFINED = "USER-DEFINED"
4691        USMALLINT = auto()
4692        UTINYINT = auto()
4693        UUID = auto()
4694        VARBINARY = auto()
4695        VARCHAR = auto()
4696        VARIANT = auto()
4697        VECTOR = auto()
4698        XML = auto()
4699        YEAR = auto()
4700        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'>
GEOGRAPHYPOINT = <Type.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NOTHING = <Type.NOTHING: 'NOTHING'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
class PseudoType(DataType):
4878class PseudoType(DataType):
4879    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4883class ObjectIdentifier(DataType):
4884    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4888class SubqueryPredicate(Predicate):
4889    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4892class All(SubqueryPredicate):
4893    pass
key = 'all'
class Any(SubqueryPredicate):
4896class Any(SubqueryPredicate):
4897    pass
key = 'any'
class Command(Expression):
4902class Command(Expression):
4903    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4906class Transaction(Expression):
4907    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4910class Commit(Expression):
4911    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4914class Rollback(Expression):
4915    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4918class Alter(Expression):
4919    arg_types = {
4920        "this": False,
4921        "kind": True,
4922        "actions": True,
4923        "exists": False,
4924        "only": False,
4925        "options": False,
4926        "cluster": False,
4927        "not_valid": False,
4928        "check": False,
4929    }
4930
4931    @property
4932    def kind(self) -> t.Optional[str]:
4933        kind = self.args.get("kind")
4934        return kind and kind.upper()
4935
4936    @property
4937    def actions(self) -> t.List[Expression]:
4938        return self.args.get("actions") or []
arg_types = {'this': False, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False, 'check': False}
kind: Optional[str]
4931    @property
4932    def kind(self) -> t.Optional[str]:
4933        kind = self.args.get("kind")
4934        return kind and kind.upper()
actions: List[Expression]
4936    @property
4937    def actions(self) -> t.List[Expression]:
4938        return self.args.get("actions") or []
key = 'alter'
class AlterSession(Expression):
4941class AlterSession(Expression):
4942    arg_types = {"expressions": True, "unset": False}
arg_types = {'expressions': True, 'unset': False}
key = 'altersession'
class Analyze(Expression):
4945class Analyze(Expression):
4946    arg_types = {
4947        "kind": False,
4948        "this": False,
4949        "options": False,
4950        "mode": False,
4951        "partition": False,
4952        "expression": False,
4953        "properties": False,
4954    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4957class AnalyzeStatistics(Expression):
4958    arg_types = {
4959        "kind": True,
4960        "option": False,
4961        "this": False,
4962        "expressions": False,
4963    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4966class AnalyzeHistogram(Expression):
4967    arg_types = {
4968        "this": True,
4969        "expressions": True,
4970        "expression": False,
4971        "update_options": False,
4972    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4975class AnalyzeSample(Expression):
4976    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4979class AnalyzeListChainedRows(Expression):
4980    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4983class AnalyzeDelete(Expression):
4984    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4987class AnalyzeWith(Expression):
4988    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4991class AnalyzeValidate(Expression):
4992    arg_types = {
4993        "kind": True,
4994        "this": False,
4995        "expression": False,
4996    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4999class AnalyzeColumns(Expression):
5000    pass
key = 'analyzecolumns'
class UsingData(Expression):
5003class UsingData(Expression):
5004    pass
key = 'usingdata'
class AddConstraint(Expression):
5007class AddConstraint(Expression):
5008    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AddPartition(Expression):
5011class AddPartition(Expression):
5012    arg_types = {"this": True, "exists": False, "location": False}
arg_types = {'this': True, 'exists': False, 'location': False}
key = 'addpartition'
class AttachOption(Expression):
5015class AttachOption(Expression):
5016    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
5019class DropPartition(Expression):
5020    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
5024class ReplacePartition(Expression):
5025    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
5029class Binary(Condition):
5030    arg_types = {"this": True, "expression": True}
5031
5032    @property
5033    def left(self) -> Expression:
5034        return self.this
5035
5036    @property
5037    def right(self) -> Expression:
5038        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
5032    @property
5033    def left(self) -> Expression:
5034        return self.this
right: Expression
5036    @property
5037    def right(self) -> Expression:
5038        return self.expression
key = 'binary'
class Add(Binary):
5041class Add(Binary):
5042    pass
key = 'add'
class Connector(Binary):
5045class Connector(Binary):
5046    pass
key = 'connector'
class BitwiseAnd(Binary):
5049class BitwiseAnd(Binary):
5050    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
5053class BitwiseLeftShift(Binary):
5054    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
5057class BitwiseOr(Binary):
5058    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
5061class BitwiseRightShift(Binary):
5062    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
5065class BitwiseXor(Binary):
5066    pass
key = 'bitwisexor'
class Div(Binary):
5069class Div(Binary):
5070    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):
5073class Overlaps(Binary):
5074    pass
key = 'overlaps'
class Dot(Binary):
5077class Dot(Binary):
5078    @property
5079    def is_star(self) -> bool:
5080        return self.expression.is_star
5081
5082    @property
5083    def name(self) -> str:
5084        return self.expression.name
5085
5086    @property
5087    def output_name(self) -> str:
5088        return self.name
5089
5090    @classmethod
5091    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5092        """Build a Dot object with a sequence of expressions."""
5093        if len(expressions) < 2:
5094            raise ValueError("Dot requires >= 2 expressions.")
5095
5096        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5097
5098    @property
5099    def parts(self) -> t.List[Expression]:
5100        """Return the parts of a table / column in order catalog, db, table."""
5101        this, *parts = self.flatten()
5102
5103        parts.reverse()
5104
5105        for arg in COLUMN_PARTS:
5106            part = this.args.get(arg)
5107
5108            if isinstance(part, Expression):
5109                parts.append(part)
5110
5111        parts.reverse()
5112        return parts
is_star: bool
5078    @property
5079    def is_star(self) -> bool:
5080        return self.expression.is_star

Checks whether an expression is a star.

name: str
5082    @property
5083    def name(self) -> str:
5084        return self.expression.name
output_name: str
5086    @property
5087    def output_name(self) -> str:
5088        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:
5090    @classmethod
5091    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5092        """Build a Dot object with a sequence of expressions."""
5093        if len(expressions) < 2:
5094            raise ValueError("Dot requires >= 2 expressions.")
5095
5096        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]
5098    @property
5099    def parts(self) -> t.List[Expression]:
5100        """Return the parts of a table / column in order catalog, db, table."""
5101        this, *parts = self.flatten()
5102
5103        parts.reverse()
5104
5105        for arg in COLUMN_PARTS:
5106            part = this.args.get(arg)
5107
5108            if isinstance(part, Expression):
5109                parts.append(part)
5110
5111        parts.reverse()
5112        return parts

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

key = 'dot'
DATA_TYPE = typing.Union[str, Identifier, Dot, DataType, DataType.Type]
class DPipe(Binary):
5118class DPipe(Binary):
5119    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5122class EQ(Binary, Predicate):
5123    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5126class NullSafeEQ(Binary, Predicate):
5127    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5130class NullSafeNEQ(Binary, Predicate):
5131    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5135class PropertyEQ(Binary):
5136    pass
key = 'propertyeq'
class Distance(Binary):
5139class Distance(Binary):
5140    pass
key = 'distance'
class Escape(Binary):
5143class Escape(Binary):
5144    pass
key = 'escape'
class Glob(Binary, Predicate):
5147class Glob(Binary, Predicate):
5148    pass
key = 'glob'
class GT(Binary, Predicate):
5151class GT(Binary, Predicate):
5152    pass
key = 'gt'
class GTE(Binary, Predicate):
5155class GTE(Binary, Predicate):
5156    pass
key = 'gte'
class ILike(Binary, Predicate):
5159class ILike(Binary, Predicate):
5160    pass
key = 'ilike'
class IntDiv(Binary):
5163class IntDiv(Binary):
5164    pass
key = 'intdiv'
class Is(Binary, Predicate):
5167class Is(Binary, Predicate):
5168    pass
key = 'is'
class Kwarg(Binary):
5171class Kwarg(Binary):
5172    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5175class Like(Binary, Predicate):
5176    pass
key = 'like'
class LT(Binary, Predicate):
5179class LT(Binary, Predicate):
5180    pass
key = 'lt'
class LTE(Binary, Predicate):
5183class LTE(Binary, Predicate):
5184    pass
key = 'lte'
class Mod(Binary):
5187class Mod(Binary):
5188    pass
key = 'mod'
class Mul(Binary):
5191class Mul(Binary):
5192    pass
key = 'mul'
class NEQ(Binary, Predicate):
5195class NEQ(Binary, Predicate):
5196    pass
key = 'neq'
class Operator(Binary):
5200class Operator(Binary):
5201    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5204class SimilarTo(Binary, Predicate):
5205    pass
key = 'similarto'
class Slice(Binary):
5208class Slice(Binary):
5209    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5212class Sub(Binary):
5213    pass
key = 'sub'
class Unary(Condition):
5218class Unary(Condition):
5219    pass
key = 'unary'
class BitwiseNot(Unary):
5222class BitwiseNot(Unary):
5223    pass
key = 'bitwisenot'
class Not(Unary):
5226class Not(Unary):
5227    pass
key = 'not'
class Paren(Unary):
5230class Paren(Unary):
5231    @property
5232    def output_name(self) -> str:
5233        return self.this.name
output_name: str
5231    @property
5232    def output_name(self) -> str:
5233        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):
5236class Neg(Unary):
5237    def to_py(self) -> int | Decimal:
5238        if self.is_number:
5239            return self.this.to_py() * -1
5240        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5237    def to_py(self) -> int | Decimal:
5238        if self.is_number:
5239            return self.this.to_py() * -1
5240        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5243class Alias(Expression):
5244    arg_types = {"this": True, "alias": False}
5245
5246    @property
5247    def output_name(self) -> str:
5248        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5246    @property
5247    def output_name(self) -> str:
5248        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):
5253class PivotAlias(Alias):
5254    pass
key = 'pivotalias'
class PivotAny(Expression):
5259class PivotAny(Expression):
5260    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5263class Aliases(Expression):
5264    arg_types = {"this": True, "expressions": True}
5265
5266    @property
5267    def aliases(self):
5268        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5266    @property
5267    def aliases(self):
5268        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5272class AtIndex(Expression):
5273    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5276class AtTimeZone(Expression):
5277    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5280class FromTimeZone(Expression):
5281    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class FormatPhrase(Expression):
5284class FormatPhrase(Expression):
5285    """Format override for a column in Teradata.
5286    Can be expanded to additional dialects as needed
5287
5288    https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT
5289    """
5290
5291    arg_types = {"this": True, "format": True}

Format override for a column in Teradata. Can be expanded to additional dialects as needed

https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT

arg_types = {'this': True, 'format': True}
key = 'formatphrase'
class Between(Predicate):
5294class Between(Predicate):
5295    arg_types = {"this": True, "low": True, "high": True, "symmetric": False}
arg_types = {'this': True, 'low': True, 'high': True, 'symmetric': False}
key = 'between'
class Bracket(Condition):
5298class Bracket(Condition):
5299    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5300    arg_types = {
5301        "this": True,
5302        "expressions": True,
5303        "offset": False,
5304        "safe": False,
5305        "returns_list_for_maps": False,
5306    }
5307
5308    @property
5309    def output_name(self) -> str:
5310        if len(self.expressions) == 1:
5311            return self.expressions[0].output_name
5312
5313        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5308    @property
5309    def output_name(self) -> str:
5310        if len(self.expressions) == 1:
5311            return self.expressions[0].output_name
5312
5313        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):
5316class Distinct(Expression):
5317    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5320class In(Predicate):
5321    arg_types = {
5322        "this": True,
5323        "expressions": False,
5324        "query": False,
5325        "unnest": False,
5326        "field": False,
5327        "is_global": False,
5328    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5332class ForIn(Expression):
5333    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5336class TimeUnit(Expression):
5337    """Automatically converts unit arg into a var."""
5338
5339    arg_types = {"unit": False}
5340
5341    UNABBREVIATED_UNIT_NAME = {
5342        "D": "DAY",
5343        "H": "HOUR",
5344        "M": "MINUTE",
5345        "MS": "MILLISECOND",
5346        "NS": "NANOSECOND",
5347        "Q": "QUARTER",
5348        "S": "SECOND",
5349        "US": "MICROSECOND",
5350        "W": "WEEK",
5351        "Y": "YEAR",
5352    }
5353
5354    VAR_LIKE = (Column, Literal, Var)
5355
5356    def __init__(self, **args):
5357        unit = args.get("unit")
5358        if type(unit) in self.VAR_LIKE:
5359            args["unit"] = Var(
5360                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5361            )
5362        elif isinstance(unit, Week):
5363            unit.set("this", Var(this=unit.this.name.upper()))
5364
5365        super().__init__(**args)
5366
5367    @property
5368    def unit(self) -> t.Optional[Var | IntervalSpan]:
5369        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5356    def __init__(self, **args):
5357        unit = args.get("unit")
5358        if type(unit) in self.VAR_LIKE:
5359            args["unit"] = Var(
5360                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5361            )
5362        elif isinstance(unit, Week):
5363            unit.set("this", Var(this=unit.this.name.upper()))
5364
5365        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]
5367    @property
5368    def unit(self) -> t.Optional[Var | IntervalSpan]:
5369        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5372class IntervalOp(TimeUnit):
5373    arg_types = {"unit": False, "expression": True}
5374
5375    def interval(self):
5376        return Interval(
5377            this=self.expression.copy(),
5378            unit=self.unit.copy() if self.unit else None,
5379        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5375    def interval(self):
5376        return Interval(
5377            this=self.expression.copy(),
5378            unit=self.unit.copy() if self.unit else None,
5379        )
key = 'intervalop'
class IntervalSpan(DataType):
5385class IntervalSpan(DataType):
5386    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5389class Interval(TimeUnit):
5390    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5393class IgnoreNulls(Expression):
5394    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5397class RespectNulls(Expression):
5398    pass
key = 'respectnulls'
class HavingMax(Expression):
5402class HavingMax(Expression):
5403    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5407class Func(Condition):
5408    """
5409    The base class for all function expressions.
5410
5411    Attributes:
5412        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5413            treated as a variable length argument and the argument's value will be stored as a list.
5414        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5415            function expression. These values are used to map this node to a name during parsing as
5416            well as to provide the function's name during SQL string generation. By default the SQL
5417            name is set to the expression's class name transformed to snake case.
5418    """
5419
5420    is_var_len_args = False
5421
5422    @classmethod
5423    def from_arg_list(cls, args):
5424        if cls.is_var_len_args:
5425            all_arg_keys = list(cls.arg_types)
5426            # If this function supports variable length argument treat the last argument as such.
5427            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5428            num_non_var = len(non_var_len_arg_keys)
5429
5430            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5431            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5432        else:
5433            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5434
5435        return cls(**args_dict)
5436
5437    @classmethod
5438    def sql_names(cls):
5439        if cls is Func:
5440            raise NotImplementedError(
5441                "SQL name is only supported by concrete function implementations"
5442            )
5443        if "_sql_names" not in cls.__dict__:
5444            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5445        return cls._sql_names
5446
5447    @classmethod
5448    def sql_name(cls):
5449        sql_names = cls.sql_names()
5450        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5451        return sql_names[0]
5452
5453    @classmethod
5454    def default_parser_mappings(cls):
5455        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):
5422    @classmethod
5423    def from_arg_list(cls, args):
5424        if cls.is_var_len_args:
5425            all_arg_keys = list(cls.arg_types)
5426            # If this function supports variable length argument treat the last argument as such.
5427            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5428            num_non_var = len(non_var_len_arg_keys)
5429
5430            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5431            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5432        else:
5433            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5434
5435        return cls(**args_dict)
@classmethod
def sql_names(cls):
5437    @classmethod
5438    def sql_names(cls):
5439        if cls is Func:
5440            raise NotImplementedError(
5441                "SQL name is only supported by concrete function implementations"
5442            )
5443        if "_sql_names" not in cls.__dict__:
5444            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5445        return cls._sql_names
@classmethod
def sql_name(cls):
5447    @classmethod
5448    def sql_name(cls):
5449        sql_names = cls.sql_names()
5450        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5451        return sql_names[0]
@classmethod
def default_parser_mappings(cls):
5453    @classmethod
5454    def default_parser_mappings(cls):
5455        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5458class Typeof(Func):
5459    pass
key = 'typeof'
class Acos(Func):
5462class Acos(Func):
5463    pass
key = 'acos'
class Acosh(Func):
5466class Acosh(Func):
5467    pass
key = 'acosh'
class Asin(Func):
5470class Asin(Func):
5471    pass
key = 'asin'
class Asinh(Func):
5474class Asinh(Func):
5475    pass
key = 'asinh'
class Atan(Func):
5478class Atan(Func):
5479    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'atan'
class Atanh(Func):
5482class Atanh(Func):
5483    pass
key = 'atanh'
class Atan2(Func):
5486class Atan2(Func):
5487    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atan2'
class Cot(Func):
5490class Cot(Func):
5491    pass
key = 'cot'
class Coth(Func):
5494class Coth(Func):
5495    pass
key = 'coth'
class Csc(Func):
5498class Csc(Func):
5499    pass
key = 'csc'
class Csch(Func):
5502class Csch(Func):
5503    pass
key = 'csch'
class Sec(Func):
5506class Sec(Func):
5507    pass
key = 'sec'
class Sech(Func):
5510class Sech(Func):
5511    pass
key = 'sech'
class Sin(Func):
5514class Sin(Func):
5515    pass
key = 'sin'
class Sinh(Func):
5518class Sinh(Func):
5519    pass
key = 'sinh'
class CosineDistance(Func):
5522class CosineDistance(Func):
5523    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'cosinedistance'
class EuclideanDistance(Func):
5526class EuclideanDistance(Func):
5527    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'euclideandistance'
class AggFunc(Func):
5530class AggFunc(Func):
5531    pass
key = 'aggfunc'
class BitwiseAndAgg(AggFunc):
5534class BitwiseAndAgg(AggFunc):
5535    pass
key = 'bitwiseandagg'
class BitwiseOrAgg(AggFunc):
5538class BitwiseOrAgg(AggFunc):
5539    pass
key = 'bitwiseoragg'
class BitwiseXorAgg(AggFunc):
5542class BitwiseXorAgg(AggFunc):
5543    pass
key = 'bitwisexoragg'
class BitwiseCountAgg(AggFunc):
5546class BitwiseCountAgg(AggFunc):
5547    pass
key = 'bitwisecountagg'
class ByteLength(Func):
5550class ByteLength(Func):
5551    pass
key = 'bytelength'
class JSONBool(Func):
5555class JSONBool(Func):
5556    pass
key = 'jsonbool'
class ArrayRemove(Func):
5559class ArrayRemove(Func):
5560    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5563class ParameterizedAgg(AggFunc):
5564    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5567class Abs(Func):
5568    pass
key = 'abs'
class ArgMax(AggFunc):
5571class ArgMax(AggFunc):
5572    arg_types = {"this": True, "expression": True, "count": False}
5573    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5576class ArgMin(AggFunc):
5577    arg_types = {"this": True, "expression": True, "count": False}
5578    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5581class ApproxTopK(AggFunc):
5582    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class ApproxTopSum(AggFunc):
5585class ApproxTopSum(AggFunc):
5586    arg_types = {"this": True, "expression": True, "count": True}
arg_types = {'this': True, 'expression': True, 'count': True}
key = 'approxtopsum'
class ApproxQuantiles(AggFunc):
5589class ApproxQuantiles(AggFunc):
5590    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'approxquantiles'
class FarmFingerprint(Func):
5593class FarmFingerprint(Func):
5594    arg_types = {"expressions": True}
5595    is_var_len_args = True
5596    _sql_names = ["FARM_FINGERPRINT", "FARMFINGERPRINT64"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'farmfingerprint'
class Flatten(Func):
5599class Flatten(Func):
5600    pass
key = 'flatten'
class Float64(Func):
5603class Float64(Func):
5604    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'float64'
class Transform(Func):
5608class Transform(Func):
5609    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Translate(Func):
5612class Translate(Func):
5613    arg_types = {"this": True, "from": True, "to": True}
arg_types = {'this': True, 'from': True, 'to': True}
key = 'translate'
class Grouping(AggFunc):
5616class Grouping(AggFunc):
5617    arg_types = {"expressions": True}
5618    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'grouping'
class Anonymous(Func):
5621class Anonymous(Func):
5622    arg_types = {"this": True, "expressions": False}
5623    is_var_len_args = True
5624
5625    @property
5626    def name(self) -> str:
5627        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
5625    @property
5626    def name(self) -> str:
5627        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5630class AnonymousAggFunc(AggFunc):
5631    arg_types = {"this": True, "expressions": False}
5632    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5636class CombinedAggFunc(AnonymousAggFunc):
5637    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5640class CombinedParameterizedAgg(ParameterizedAgg):
5641    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5646class Hll(AggFunc):
5647    arg_types = {"this": True, "expressions": False}
5648    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5651class ApproxDistinct(AggFunc):
5652    arg_types = {"this": True, "accuracy": False}
5653    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5656class Apply(Func):
5657    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5660class Array(Func):
5661    arg_types = {"expressions": False, "bracket_notation": False}
5662    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5665class Ascii(Func):
5666    pass
key = 'ascii'
class ToArray(Func):
5670class ToArray(Func):
5671    pass
key = 'toarray'
class List(Func):
5675class List(Func):
5676    arg_types = {"expressions": False}
5677    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5681class Pad(Func):
5682    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):
5687class ToChar(Func):
5688    arg_types = {
5689        "this": True,
5690        "format": False,
5691        "nlsparam": False,
5692        "is_numeric": False,
5693    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'is_numeric': False}
key = 'tochar'
class ToCodePoints(Func):
5696class ToCodePoints(Func):
5697    pass
key = 'tocodepoints'
class ToNumber(Func):
5702class ToNumber(Func):
5703    arg_types = {
5704        "this": True,
5705        "format": False,
5706        "nlsparam": False,
5707        "precision": False,
5708        "scale": False,
5709    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5713class ToDouble(Func):
5714    arg_types = {
5715        "this": True,
5716        "format": False,
5717    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class CodePointsToBytes(Func):
5720class CodePointsToBytes(Func):
5721    pass
key = 'codepointstobytes'
class Columns(Func):
5724class Columns(Func):
5725    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5729class Convert(Func):
5730    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5734class ConvertToCharset(Func):
5735    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5738class ConvertTimezone(Func):
5739    arg_types = {
5740        "source_tz": False,
5741        "target_tz": True,
5742        "timestamp": True,
5743        "options": False,
5744    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class CodePointsToString(Func):
5747class CodePointsToString(Func):
5748    pass
key = 'codepointstostring'
class GenerateSeries(Func):
5751class GenerateSeries(Func):
5752    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):
5758class ExplodingGenerateSeries(GenerateSeries):
5759    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5762class ArrayAgg(AggFunc):
5763    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5766class ArrayUniqueAgg(AggFunc):
5767    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5770class ArrayAll(Func):
5771    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5775class ArrayAny(Func):
5776    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5779class ArrayConcat(Func):
5780    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5781    arg_types = {"this": True, "expressions": False}
5782    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5785class ArrayConcatAgg(AggFunc):
5786    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5789class ArrayConstructCompact(Func):
5790    arg_types = {"expressions": True}
5791    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5794class ArrayContains(Binary, Func):
5795    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5798class ArrayContainsAll(Binary, Func):
5799    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5802class ArrayFilter(Func):
5803    arg_types = {"this": True, "expression": True}
5804    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5807class ArrayFirst(Func):
5808    pass
key = 'arrayfirst'
class ArrayLast(Func):
5811class ArrayLast(Func):
5812    pass
key = 'arraylast'
class ArrayReverse(Func):
5815class ArrayReverse(Func):
5816    pass
key = 'arrayreverse'
class ArraySlice(Func):
5819class ArraySlice(Func):
5820    arg_types = {"this": True, "start": True, "end": False, "step": False}
arg_types = {'this': True, 'start': True, 'end': False, 'step': False}
key = 'arrayslice'
class ArrayToString(Func):
5823class ArrayToString(Func):
5824    arg_types = {"this": True, "expression": True, "null": False}
5825    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5828class ArrayIntersect(Func):
5829    arg_types = {"expressions": True}
5830    is_var_len_args = True
5831    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5834class StPoint(Func):
5835    arg_types = {"this": True, "expression": True, "null": False}
5836    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5839class StDistance(Func):
5840    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5844class String(Func):
5845    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5848class StringToArray(Func):
5849    arg_types = {"this": True, "expression": False, "null": False}
5850    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
arg_types = {'this': True, 'expression': False, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5853class ArrayOverlaps(Binary, Func):
5854    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5857class ArraySize(Func):
5858    arg_types = {"this": True, "expression": False}
5859    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5862class ArraySort(Func):
5863    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5866class ArraySum(Func):
5867    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5870class ArrayUnionAgg(AggFunc):
5871    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5874class Avg(AggFunc):
5875    pass
key = 'avg'
class AnyValue(AggFunc):
5878class AnyValue(AggFunc):
5879    pass
key = 'anyvalue'
class Lag(AggFunc):
5882class Lag(AggFunc):
5883    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5886class Lead(AggFunc):
5887    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5892class First(AggFunc):
5893    pass
key = 'first'
class Last(AggFunc):
5896class Last(AggFunc):
5897    pass
key = 'last'
class FirstValue(AggFunc):
5900class FirstValue(AggFunc):
5901    pass
key = 'firstvalue'
class LastValue(AggFunc):
5904class LastValue(AggFunc):
5905    pass
key = 'lastvalue'
class NthValue(AggFunc):
5908class NthValue(AggFunc):
5909    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5912class Case(Func):
5913    arg_types = {"this": False, "ifs": True, "default": False}
5914
5915    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5916        instance = maybe_copy(self, copy)
5917        instance.append(
5918            "ifs",
5919            If(
5920                this=maybe_parse(condition, copy=copy, **opts),
5921                true=maybe_parse(then, copy=copy, **opts),
5922            ),
5923        )
5924        return instance
5925
5926    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5927        instance = maybe_copy(self, copy)
5928        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5929        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:
5915    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5916        instance = maybe_copy(self, copy)
5917        instance.append(
5918            "ifs",
5919            If(
5920                this=maybe_parse(condition, copy=copy, **opts),
5921                true=maybe_parse(then, copy=copy, **opts),
5922            ),
5923        )
5924        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5926    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5927        instance = maybe_copy(self, copy)
5928        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5929        return instance
key = 'case'
class Cast(Func):
5932class Cast(Func):
5933    arg_types = {
5934        "this": True,
5935        "to": True,
5936        "format": False,
5937        "safe": False,
5938        "action": False,
5939        "default": False,
5940    }
5941
5942    @property
5943    def name(self) -> str:
5944        return self.this.name
5945
5946    @property
5947    def to(self) -> DataType:
5948        return self.args["to"]
5949
5950    @property
5951    def output_name(self) -> str:
5952        return self.name
5953
5954    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5955        """
5956        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5957        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5958        array<int> != array<float>.
5959
5960        Args:
5961            dtypes: the data types to compare this Cast's DataType to.
5962
5963        Returns:
5964            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5965        """
5966        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5942    @property
5943    def name(self) -> str:
5944        return self.this.name
to: DataType
5946    @property
5947    def to(self) -> DataType:
5948        return self.args["to"]
output_name: str
5950    @property
5951    def output_name(self) -> str:
5952        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, Identifier, Dot, DataType, DataType.Type]) -> bool:
5954    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5955        """
5956        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5957        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5958        array<int> != array<float>.
5959
5960        Args:
5961            dtypes: the data types to compare this Cast's DataType to.
5962
5963        Returns:
5964            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5965        """
5966        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):
5969class TryCast(Cast):
5970    arg_types = {**Cast.arg_types, "requires_string": False}
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False, 'requires_string': False}
key = 'trycast'
class JSONCast(Cast):
5974class JSONCast(Cast):
5975    pass
key = 'jsoncast'
class JustifyDays(Func):
5978class JustifyDays(Func):
5979    pass
key = 'justifydays'
class JustifyHours(Func):
5982class JustifyHours(Func):
5983    pass
key = 'justifyhours'
class JustifyInterval(Func):
5986class JustifyInterval(Func):
5987    pass
key = 'justifyinterval'
class Try(Func):
5990class Try(Func):
5991    pass
key = 'try'
class CastToStrType(Func):
5994class CastToStrType(Func):
5995    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5999class TranslateCharacters(Expression):
6000    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
6003class Collate(Binary, Func):
6004    pass
key = 'collate'
class Ceil(Func):
6007class Ceil(Func):
6008    arg_types = {"this": True, "decimals": False, "to": False}
6009    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
6012class Coalesce(Func):
6013    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
6014    is_var_len_args = True
6015    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False, 'is_null': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
6018class Chr(Func):
6019    arg_types = {"expressions": True, "charset": False}
6020    is_var_len_args = True
6021    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
6024class Concat(Func):
6025    arg_types = {"expressions": True, "safe": False, "coalesce": False}
6026    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
6029class ConcatWs(Concat):
6030    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
6034class Contains(Func):
6035    arg_types = {"this": True, "expression": True, "json_scope": False}
arg_types = {'this': True, 'expression': True, 'json_scope': False}
key = 'contains'
class ConnectByRoot(Func):
6039class ConnectByRoot(Func):
6040    pass
key = 'connectbyroot'
class Count(AggFunc):
6043class Count(AggFunc):
6044    arg_types = {"this": False, "expressions": False, "big_int": False}
6045    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
6048class CountIf(AggFunc):
6049    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
6053class Cbrt(Func):
6054    pass
key = 'cbrt'
class CurrentDate(Func):
6057class CurrentDate(Func):
6058    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
6061class CurrentDatetime(Func):
6062    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
6065class CurrentTime(Func):
6066    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
6069class CurrentTimestamp(Func):
6070    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
6073class CurrentTimestampLTZ(Func):
6074    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
6077class CurrentSchema(Func):
6078    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
6081class CurrentUser(Func):
6082    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class UtcDate(Func):
6085class UtcDate(Func):
6086    arg_types = {}
arg_types = {}
key = 'utcdate'
class UtcTime(Func):
6089class UtcTime(Func):
6090    arg_types = {"this": False}
arg_types = {'this': False}
key = 'utctime'
class UtcTimestamp(Func):
6093class UtcTimestamp(Func):
6094    arg_types = {"this": False}
arg_types = {'this': False}
key = 'utctimestamp'
class DateAdd(Func, IntervalOp):
6097class DateAdd(Func, IntervalOp):
6098    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
6101class DateBin(Func, IntervalOp):
6102    arg_types = {"this": True, "expression": True, "unit": False, "zone": False, "origin": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False, 'origin': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
6105class DateSub(Func, IntervalOp):
6106    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
6109class DateDiff(Func, TimeUnit):
6110    _sql_names = ["DATEDIFF", "DATE_DIFF"]
6111    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datediff'
class DateTrunc(Func):
6114class DateTrunc(Func):
6115    arg_types = {"unit": True, "this": True, "zone": False}
6116
6117    def __init__(self, **args):
6118        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6119        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6120        unabbreviate = args.pop("unabbreviate", True)
6121
6122        unit = args.get("unit")
6123        if isinstance(unit, TimeUnit.VAR_LIKE):
6124            unit_name = unit.name.upper()
6125            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6126                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6127
6128            args["unit"] = Literal.string(unit_name)
6129
6130        super().__init__(**args)
6131
6132    @property
6133    def unit(self) -> Expression:
6134        return self.args["unit"]
DateTrunc(**args)
6117    def __init__(self, **args):
6118        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6119        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6120        unabbreviate = args.pop("unabbreviate", True)
6121
6122        unit = args.get("unit")
6123        if isinstance(unit, TimeUnit.VAR_LIKE):
6124            unit_name = unit.name.upper()
6125            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6126                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6127
6128            args["unit"] = Literal.string(unit_name)
6129
6130        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
6132    @property
6133    def unit(self) -> Expression:
6134        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
6139class Datetime(Func):
6140    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
6143class DatetimeAdd(Func, IntervalOp):
6144    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
6147class DatetimeSub(Func, IntervalOp):
6148    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
6151class DatetimeDiff(Func, TimeUnit):
6152    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
6155class DatetimeTrunc(Func, TimeUnit):
6156    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DateFromUnixDate(Func):
6159class DateFromUnixDate(Func):
6160    pass
key = 'datefromunixdate'
class DayOfWeek(Func):
6163class DayOfWeek(Func):
6164    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
6169class DayOfWeekIso(Func):
6170    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
6173class DayOfMonth(Func):
6174    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
6177class DayOfYear(Func):
6178    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
6181class ToDays(Func):
6182    pass
key = 'todays'
class WeekOfYear(Func):
6185class WeekOfYear(Func):
6186    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
6189class MonthsBetween(Func):
6190    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
6193class MakeInterval(Func):
6194    arg_types = {
6195        "year": False,
6196        "month": False,
6197        "day": False,
6198        "hour": False,
6199        "minute": False,
6200        "second": False,
6201    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
6204class LastDay(Func, TimeUnit):
6205    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
6206    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class LaxBool(Func):
6209class LaxBool(Func):
6210    pass
key = 'laxbool'
class LaxFloat64(Func):
6213class LaxFloat64(Func):
6214    pass
key = 'laxfloat64'
class LaxInt64(Func):
6217class LaxInt64(Func):
6218    pass
key = 'laxint64'
class LaxString(Func):
6221class LaxString(Func):
6222    pass
key = 'laxstring'
class Extract(Func):
6225class Extract(Func):
6226    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6229class Exists(Func, SubqueryPredicate):
6230    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6233class Timestamp(Func):
6234    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6237class TimestampAdd(Func, TimeUnit):
6238    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6241class TimestampSub(Func, TimeUnit):
6242    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6245class TimestampDiff(Func, TimeUnit):
6246    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6247    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6250class TimestampTrunc(Func, TimeUnit):
6251    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6254class TimeAdd(Func, TimeUnit):
6255    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6258class TimeSub(Func, TimeUnit):
6259    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6262class TimeDiff(Func, TimeUnit):
6263    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6266class TimeTrunc(Func, TimeUnit):
6267    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6270class DateFromParts(Func):
6271    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6272    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6275class TimeFromParts(Func):
6276    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6277    arg_types = {
6278        "hour": True,
6279        "min": True,
6280        "sec": True,
6281        "nano": False,
6282        "fractions": False,
6283        "precision": False,
6284    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6287class DateStrToDate(Func):
6288    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6291class DateToDateStr(Func):
6292    pass
key = 'datetodatestr'
class DateToDi(Func):
6295class DateToDi(Func):
6296    pass
key = 'datetodi'
class Date(Func):
6300class Date(Func):
6301    arg_types = {"this": False, "zone": False, "expressions": False}
6302    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6305class Day(Func):
6306    pass
key = 'day'
class Decode(Func):
6309class Decode(Func):
6310    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6313class DecodeCase(Func):
6314    arg_types = {"expressions": True}
6315    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DenseRank(AggFunc):
6318class DenseRank(AggFunc):
6319    arg_types = {"expressions": False}
6320    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'denserank'
class DiToDate(Func):
6323class DiToDate(Func):
6324    pass
key = 'ditodate'
class Encode(Func):
6327class Encode(Func):
6328    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6331class Exp(Func):
6332    pass
key = 'exp'
class Explode(Func, UDTF):
6336class Explode(Func, UDTF):
6337    arg_types = {"this": True, "expressions": False}
6338    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6342class Inline(Func):
6343    pass
key = 'inline'
class ExplodeOuter(Explode):
6346class ExplodeOuter(Explode):
6347    pass
key = 'explodeouter'
class Posexplode(Explode):
6350class Posexplode(Explode):
6351    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6354class PosexplodeOuter(Posexplode, ExplodeOuter):
6355    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6358class PositionalColumn(Expression):
6359    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6362class Unnest(Func, UDTF):
6363    arg_types = {
6364        "expressions": True,
6365        "alias": False,
6366        "offset": False,
6367        "explode_array": False,
6368    }
6369
6370    @property
6371    def selects(self) -> t.List[Expression]:
6372        columns = super().selects
6373        offset = self.args.get("offset")
6374        if offset:
6375            columns = columns + [to_identifier("offset") if offset is True else offset]
6376        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6370    @property
6371    def selects(self) -> t.List[Expression]:
6372        columns = super().selects
6373        offset = self.args.get("offset")
6374        if offset:
6375            columns = columns + [to_identifier("offset") if offset is True else offset]
6376        return columns
key = 'unnest'
class Floor(Func):
6379class Floor(Func):
6380    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase32(Func):
6383class FromBase32(Func):
6384    pass
key = 'frombase32'
class FromBase64(Func):
6387class FromBase64(Func):
6388    pass
key = 'frombase64'
class ToBase32(Func):
6391class ToBase32(Func):
6392    pass
key = 'tobase32'
class ToBase64(Func):
6395class ToBase64(Func):
6396    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6400class FromISO8601Timestamp(Func):
6401    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6404class GapFill(Func):
6405    arg_types = {
6406        "this": True,
6407        "ts_column": True,
6408        "bucket_width": True,
6409        "partitioning_columns": False,
6410        "value_columns": False,
6411        "origin": False,
6412        "ignore_nulls": False,
6413    }
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):
6417class GenerateDateArray(Func):
6418    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6422class GenerateTimestampArray(Func):
6423    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class GetExtract(Func):
6427class GetExtract(Func):
6428    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'getextract'
class Greatest(Func):
6431class Greatest(Func):
6432    arg_types = {"this": True, "expressions": False}
6433    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6438class OverflowTruncateBehavior(Expression):
6439    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6442class GroupConcat(AggFunc):
6443    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6446class Hex(Func):
6447    pass
key = 'hex'
class LowerHex(Hex):
6450class LowerHex(Hex):
6451    pass
key = 'lowerhex'
class And(Connector, Func):
6454class And(Connector, Func):
6455    pass
key = 'and'
class Or(Connector, Func):
6458class Or(Connector, Func):
6459    pass
key = 'or'
class Xor(Connector, Func):
6462class Xor(Connector, Func):
6463    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6466class If(Func):
6467    arg_types = {"this": True, "true": True, "false": False}
6468    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6471class Nullif(Func):
6472    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6475class Initcap(Func):
6476    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6479class IsAscii(Func):
6480    pass
key = 'isascii'
class IsNan(Func):
6483class IsNan(Func):
6484    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6488class Int64(Func):
6489    pass
key = 'int64'
class IsInf(Func):
6492class IsInf(Func):
6493    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6497class JSON(Expression):
6498    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6501class JSONPath(Expression):
6502    arg_types = {"expressions": True, "escape": False}
6503
6504    @property
6505    def output_name(self) -> str:
6506        last_segment = self.expressions[-1].this
6507        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6504    @property
6505    def output_name(self) -> str:
6506        last_segment = self.expressions[-1].this
6507        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):
6510class JSONPathPart(Expression):
6511    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6514class JSONPathFilter(JSONPathPart):
6515    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6518class JSONPathKey(JSONPathPart):
6519    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6522class JSONPathRecursive(JSONPathPart):
6523    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6526class JSONPathRoot(JSONPathPart):
6527    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6530class JSONPathScript(JSONPathPart):
6531    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6534class JSONPathSlice(JSONPathPart):
6535    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6538class JSONPathSelector(JSONPathPart):
6539    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6542class JSONPathSubscript(JSONPathPart):
6543    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6546class JSONPathUnion(JSONPathPart):
6547    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6550class JSONPathWildcard(JSONPathPart):
6551    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6554class FormatJson(Expression):
6555    pass
key = 'formatjson'
class Format(Func):
6558class Format(Func):
6559    arg_types = {"this": True, "expressions": True}
6560    is_var_len_args = True
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'format'
class JSONKeyValue(Expression):
6563class JSONKeyValue(Expression):
6564    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONKeysAtDepth(Func):
6568class JSONKeysAtDepth(Func):
6569    arg_types = {"this": True, "expression": False, "mode": False}
arg_types = {'this': True, 'expression': False, 'mode': False}
key = 'jsonkeysatdepth'
class JSONObject(Func):
6572class JSONObject(Func):
6573    arg_types = {
6574        "expressions": False,
6575        "null_handling": False,
6576        "unique_keys": False,
6577        "return_type": False,
6578        "encoding": False,
6579    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6582class JSONObjectAgg(AggFunc):
6583    arg_types = {
6584        "expressions": False,
6585        "null_handling": False,
6586        "unique_keys": False,
6587        "return_type": False,
6588        "encoding": False,
6589    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6593class JSONBObjectAgg(AggFunc):
6594    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6598class JSONArray(Func):
6599    arg_types = {
6600        "expressions": False,
6601        "null_handling": False,
6602        "return_type": False,
6603        "strict": False,
6604    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6608class JSONArrayAgg(Func):
6609    arg_types = {
6610        "this": True,
6611        "order": False,
6612        "null_handling": False,
6613        "return_type": False,
6614        "strict": False,
6615    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6618class JSONExists(Func):
6619    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):
6624class JSONColumnDef(Expression):
6625    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):
6628class JSONSchema(Expression):
6629    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONSet(Func):
6632class JSONSet(Func):
6633    arg_types = {"this": True, "expressions": True}
6634    is_var_len_args = True
6635    _sql_names = ["JSON_SET"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonset'
class JSONStripNulls(Func):
6639class JSONStripNulls(Func):
6640    arg_types = {
6641        "this": True,
6642        "expression": False,
6643        "include_arrays": False,
6644        "remove_empty": False,
6645    }
6646    _sql_names = ["JSON_STRIP_NULLS"]
arg_types = {'this': True, 'expression': False, 'include_arrays': False, 'remove_empty': False}
key = 'jsonstripnulls'
class JSONValue(Expression):
6650class JSONValue(Expression):
6651    arg_types = {
6652        "this": True,
6653        "path": True,
6654        "returning": False,
6655        "on_condition": False,
6656    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6659class JSONValueArray(Func):
6660    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONRemove(Func):
6663class JSONRemove(Func):
6664    arg_types = {"this": True, "expressions": True}
6665    is_var_len_args = True
6666    _sql_names = ["JSON_REMOVE"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonremove'
class JSONTable(Func):
6670class JSONTable(Func):
6671    arg_types = {
6672        "this": True,
6673        "schema": True,
6674        "path": False,
6675        "error_handling": False,
6676        "empty_handling": False,
6677    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6682class JSONType(Func):
6683    arg_types = {"this": True, "expression": False}
6684    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6688class ObjectInsert(Func):
6689    arg_types = {
6690        "this": True,
6691        "key": True,
6692        "value": True,
6693        "update_flag": False,
6694    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6697class OpenJSONColumnDef(Expression):
6698    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):
6701class OpenJSON(Func):
6702    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6705class JSONBContains(Binary, Func):
6706    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBContainsAnyTopKeys(Binary, Func):
6710class JSONBContainsAnyTopKeys(Binary, Func):
6711    pass
key = 'jsonbcontainsanytopkeys'
class JSONBContainsAllTopKeys(Binary, Func):
6715class JSONBContainsAllTopKeys(Binary, Func):
6716    pass
key = 'jsonbcontainsalltopkeys'
class JSONBExists(Func):
6719class JSONBExists(Func):
6720    arg_types = {"this": True, "path": True}
6721    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONBDeleteAtPath(Binary, Func):
6725class JSONBDeleteAtPath(Binary, Func):
6726    pass
key = 'jsonbdeleteatpath'
class JSONExtract(Binary, Func):
6729class JSONExtract(Binary, Func):
6730    arg_types = {
6731        "this": True,
6732        "expression": True,
6733        "only_json_types": False,
6734        "expressions": False,
6735        "variant_extract": False,
6736        "json_query": False,
6737        "option": False,
6738        "quote": False,
6739        "on_condition": False,
6740        "requires_json": False,
6741    }
6742    _sql_names = ["JSON_EXTRACT"]
6743    is_var_len_args = True
6744
6745    @property
6746    def output_name(self) -> str:
6747        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, 'requires_json': False}
is_var_len_args = True
output_name: str
6745    @property
6746    def output_name(self) -> str:
6747        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):
6751class JSONExtractQuote(Expression):
6752    arg_types = {
6753        "option": True,
6754        "scalar": False,
6755    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6758class JSONExtractArray(Func):
6759    arg_types = {"this": True, "expression": False}
6760    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6763class JSONExtractScalar(Binary, Func):
6764    arg_types = {
6765        "this": True,
6766        "expression": True,
6767        "only_json_types": False,
6768        "expressions": False,
6769        "json_type": False,
6770    }
6771    _sql_names = ["JSON_EXTRACT_SCALAR"]
6772    is_var_len_args = True
6773
6774    @property
6775    def output_name(self) -> str:
6776        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'json_type': False}
is_var_len_args = True
output_name: str
6774    @property
6775    def output_name(self) -> str:
6776        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):
6779class JSONBExtract(Binary, Func):
6780    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6783class JSONBExtractScalar(Binary, Func):
6784    arg_types = {"this": True, "expression": True, "json_type": False}
6785    _sql_names = ["JSONB_EXTRACT_SCALAR"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonbextractscalar'
class JSONFormat(Func):
6788class JSONFormat(Func):
6789    arg_types = {"this": False, "options": False, "is_json": False, "to_json": False}
6790    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False, 'to_json': False}
key = 'jsonformat'
class JSONArrayAppend(Func):
6793class JSONArrayAppend(Func):
6794    arg_types = {"this": True, "expressions": True}
6795    is_var_len_args = True
6796    _sql_names = ["JSON_ARRAY_APPEND"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayappend'
class JSONArrayContains(Binary, Predicate, Func):
6800class JSONArrayContains(Binary, Predicate, Func):
6801    arg_types = {"this": True, "expression": True, "json_type": False}
6802    _sql_names = ["JSON_ARRAY_CONTAINS"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonarraycontains'
class JSONArrayInsert(Func):
6805class JSONArrayInsert(Func):
6806    arg_types = {"this": True, "expressions": True}
6807    is_var_len_args = True
6808    _sql_names = ["JSON_ARRAY_INSERT"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayinsert'
class ParseBignumeric(Func):
6811class ParseBignumeric(Func):
6812    pass
key = 'parsebignumeric'
class ParseNumeric(Func):
6815class ParseNumeric(Func):
6816    pass
key = 'parsenumeric'
class ParseJSON(Func):
6819class ParseJSON(Func):
6820    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6821    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6822    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6823    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class ParseTime(Func):
6826class ParseTime(Func):
6827    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'parsetime'
class ParseDatetime(Func):
6830class ParseDatetime(Func):
6831    arg_types = {"this": True, "format": False, "zone": False}
arg_types = {'this': True, 'format': False, 'zone': False}
key = 'parsedatetime'
class Least(Func):
6834class Least(Func):
6835    arg_types = {"this": True, "expressions": False}
6836    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6839class Left(Func):
6840    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Reverse(Func):
6847class Reverse(Func):
6848    pass
key = 'reverse'
class Length(Func):
6851class Length(Func):
6852    arg_types = {"this": True, "binary": False, "encoding": False}
6853    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6856class Levenshtein(Func):
6857    arg_types = {
6858        "this": True,
6859        "expression": False,
6860        "ins_cost": False,
6861        "del_cost": False,
6862        "sub_cost": False,
6863        "max_dist": False,
6864    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6867class Ln(Func):
6868    pass
key = 'ln'
class Log(Func):
6871class Log(Func):
6872    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6875class LogicalOr(AggFunc):
6876    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6879class LogicalAnd(AggFunc):
6880    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6883class Lower(Func):
6884    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6887class Map(Func):
6888    arg_types = {"keys": False, "values": False}
6889
6890    @property
6891    def keys(self) -> t.List[Expression]:
6892        keys = self.args.get("keys")
6893        return keys.expressions if keys else []
6894
6895    @property
6896    def values(self) -> t.List[Expression]:
6897        values = self.args.get("values")
6898        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6890    @property
6891    def keys(self) -> t.List[Expression]:
6892        keys = self.args.get("keys")
6893        return keys.expressions if keys else []
values: List[Expression]
6895    @property
6896    def values(self) -> t.List[Expression]:
6897        values = self.args.get("values")
6898        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6902class ToMap(Func):
6903    pass
key = 'tomap'
class MapFromEntries(Func):
6906class MapFromEntries(Func):
6907    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6911class ScopeResolution(Expression):
6912    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6915class Stream(Expression):
6916    pass
key = 'stream'
class StarMap(Func):
6919class StarMap(Func):
6920    pass
key = 'starmap'
class VarMap(Func):
6923class VarMap(Func):
6924    arg_types = {"keys": True, "values": True}
6925    is_var_len_args = True
6926
6927    @property
6928    def keys(self) -> t.List[Expression]:
6929        return self.args["keys"].expressions
6930
6931    @property
6932    def values(self) -> t.List[Expression]:
6933        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6927    @property
6928    def keys(self) -> t.List[Expression]:
6929        return self.args["keys"].expressions
values: List[Expression]
6931    @property
6932    def values(self) -> t.List[Expression]:
6933        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6937class MatchAgainst(Func):
6938    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6941class Max(AggFunc):
6942    arg_types = {"this": True, "expressions": False}
6943    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6946class MD5(Func):
6947    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6951class MD5Digest(Func):
6952    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6955class Median(AggFunc):
6956    pass
key = 'median'
class Min(AggFunc):
6959class Min(AggFunc):
6960    arg_types = {"this": True, "expressions": False}
6961    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6964class Month(Func):
6965    pass
key = 'month'
class AddMonths(Func):
6968class AddMonths(Func):
6969    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6972class Nvl2(Func):
6973    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Ntile(AggFunc):
6976class Ntile(AggFunc):
6977    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ntile'
class Normalize(Func):
6980class Normalize(Func):
6981    arg_types = {"this": True, "form": False, "is_casefold": False}
arg_types = {'this': True, 'form': False, 'is_casefold': False}
key = 'normalize'
class Overlay(Func):
6984class Overlay(Func):
6985    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):
6989class Predict(Func):
6990    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class MLTranslate(Func):
6994class MLTranslate(Func):
6995    arg_types = {"this": True, "expression": True, "params_struct": True}
arg_types = {'this': True, 'expression': True, 'params_struct': True}
key = 'mltranslate'
class FeaturesAtTime(Func):
6999class FeaturesAtTime(Func):
7000    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 GenerateEmbedding(Func):
7004class GenerateEmbedding(Func):
7005    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'generateembedding'
class MLForecast(Func):
7008class MLForecast(Func):
7009    arg_types = {"this": True, "expression": False, "params_struct": False}
arg_types = {'this': True, 'expression': False, 'params_struct': False}
key = 'mlforecast'
class VectorSearch(Func):
7013class VectorSearch(Func):
7014    arg_types = {
7015        "this": True,
7016        "column_to_search": True,
7017        "query_table": True,
7018        "query_column_to_search": False,
7019        "top_k": False,
7020        "distance_type": False,
7021        "options": False,
7022    }
arg_types = {'this': True, 'column_to_search': True, 'query_table': True, 'query_column_to_search': False, 'top_k': False, 'distance_type': False, 'options': False}
key = 'vectorsearch'
class Pow(Binary, Func):
7025class Pow(Binary, Func):
7026    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
7029class PercentileCont(AggFunc):
7030    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
7033class PercentileDisc(AggFunc):
7034    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class PercentRank(AggFunc):
7037class PercentRank(AggFunc):
7038    arg_types = {"expressions": False}
7039    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'percentrank'
class Quantile(AggFunc):
7042class Quantile(AggFunc):
7043    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
7046class ApproxQuantile(Quantile):
7047    arg_types = {
7048        "this": True,
7049        "quantile": True,
7050        "accuracy": False,
7051        "weight": False,
7052        "error_tolerance": False,
7053    }
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False, 'error_tolerance': False}
key = 'approxquantile'
class Quarter(Func):
7056class Quarter(Func):
7057    pass
key = 'quarter'
class Rand(Func):
7062class Rand(Func):
7063    _sql_names = ["RAND", "RANDOM"]
7064    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
7067class Randn(Func):
7068    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
7071class RangeN(Func):
7072    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class RangeBucket(Func):
7075class RangeBucket(Func):
7076    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'rangebucket'
class Rank(AggFunc):
7079class Rank(AggFunc):
7080    arg_types = {"expressions": False}
7081    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'rank'
class ReadCSV(Func):
7084class ReadCSV(Func):
7085    _sql_names = ["READ_CSV"]
7086    is_var_len_args = True
7087    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
7090class Reduce(Func):
7091    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):
7094class RegexpExtract(Func):
7095    arg_types = {
7096        "this": True,
7097        "expression": True,
7098        "position": False,
7099        "occurrence": False,
7100        "parameters": False,
7101        "group": False,
7102    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
7105class RegexpExtractAll(Func):
7106    arg_types = {
7107        "this": True,
7108        "expression": True,
7109        "position": False,
7110        "occurrence": False,
7111        "parameters": False,
7112        "group": False,
7113    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
7116class RegexpReplace(Func):
7117    arg_types = {
7118        "this": True,
7119        "expression": True,
7120        "replacement": False,
7121        "position": False,
7122        "occurrence": False,
7123        "modifiers": False,
7124    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
7127class RegexpLike(Binary, Func):
7128    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
7131class RegexpILike(Binary, Func):
7132    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpInstr(Func):
7135class RegexpInstr(Func):
7136    arg_types = {
7137        "this": True,
7138        "expression": True,
7139        "position": False,
7140        "occurrence": False,
7141        "option": False,
7142        "parameters": False,
7143        "group": False,
7144    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'option': False, 'parameters': False, 'group': False}
key = 'regexpinstr'
class RegexpSplit(Func):
7149class RegexpSplit(Func):
7150    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
7153class Repeat(Func):
7154    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
7158class Replace(Func):
7159    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
7164class Round(Func):
7165    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
7168class RowNumber(Func):
7169    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeAdd(Func):
7172class SafeAdd(Func):
7173    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safeadd'
class SafeDivide(Func):
7176class SafeDivide(Func):
7177    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SafeMultiply(Func):
7180class SafeMultiply(Func):
7181    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safemultiply'
class SafeNegate(Func):
7184class SafeNegate(Func):
7185    pass
key = 'safenegate'
class SafeSubtract(Func):
7188class SafeSubtract(Func):
7189    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safesubtract'
class SafeConvertBytesToString(Func):
7192class SafeConvertBytesToString(Func):
7193    pass
key = 'safeconvertbytestostring'
class SHA(Func):
7196class SHA(Func):
7197    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
7200class SHA2(Func):
7201    _sql_names = ["SHA2"]
7202    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
7205class Sign(Func):
7206    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
7209class SortArray(Func):
7210    arg_types = {"this": True, "asc": False, "nulls_first": False}
arg_types = {'this': True, 'asc': False, 'nulls_first': False}
key = 'sortarray'
class Soundex(Func):
7213class Soundex(Func):
7214    pass
key = 'soundex'
class Split(Func):
7217class Split(Func):
7218    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
7222class SplitPart(Func):
7223    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
7228class Substring(Func):
7229    _sql_names = ["SUBSTRING", "SUBSTR"]
7230    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
7233class SubstringIndex(Func):
7234    """
7235    SUBSTRING_INDEX(str, delim, count)
7236
7237    *count* > 0  → left slice before the *count*-th delimiter
7238    *count* < 0  → right slice after the |count|-th delimiter
7239    """
7240
7241    arg_types = {"this": True, "delimiter": True, "count": True}

SUBSTRING_INDEX(str, delim, count)

count > 0 → left slice before the count-th delimiter count < 0 → right slice after the |count|-th delimiter

arg_types = {'this': True, 'delimiter': True, 'count': True}
key = 'substringindex'
class StandardHash(Func):
7244class StandardHash(Func):
7245    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
7248class StartsWith(Func):
7249    _sql_names = ["STARTS_WITH", "STARTSWITH"]
7250    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
7253class EndsWith(Func):
7254    _sql_names = ["ENDS_WITH", "ENDSWITH"]
7255    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
7258class StrPosition(Func):
7259    arg_types = {
7260        "this": True,
7261        "substr": True,
7262        "position": False,
7263        "occurrence": False,
7264    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
7267class StrToDate(Func):
7268    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
7271class StrToTime(Func):
7272    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):
7277class StrToUnix(Func):
7278    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
7283class StrToMap(Func):
7284    arg_types = {
7285        "this": True,
7286        "pair_delim": False,
7287        "key_value_delim": False,
7288        "duplicate_resolution_callback": False,
7289    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
7292class NumberToStr(Func):
7293    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
7296class FromBase(Func):
7297    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
7300class Space(Func):
7301    """
7302    SPACE(n) → string consisting of n blank characters
7303    """
7304
7305    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
7308class Struct(Func):
7309    arg_types = {"expressions": False}
7310    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
7313class StructExtract(Func):
7314    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
7319class Stuff(Func):
7320    _sql_names = ["STUFF", "INSERT"]
7321    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):
7324class Sum(AggFunc):
7325    pass
key = 'sum'
class Sqrt(Func):
7328class Sqrt(Func):
7329    pass
key = 'sqrt'
class Stddev(AggFunc):
7332class Stddev(AggFunc):
7333    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
7336class StddevPop(AggFunc):
7337    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
7340class StddevSamp(AggFunc):
7341    pass
key = 'stddevsamp'
class Time(Func):
7345class Time(Func):
7346    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
7349class TimeToStr(Func):
7350    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):
7353class TimeToTimeStr(Func):
7354    pass
key = 'timetotimestr'
class TimeToUnix(Func):
7357class TimeToUnix(Func):
7358    pass
key = 'timetounix'
class TimeStrToDate(Func):
7361class TimeStrToDate(Func):
7362    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
7365class TimeStrToTime(Func):
7366    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
7369class TimeStrToUnix(Func):
7370    pass
key = 'timestrtounix'
class Trim(Func):
7373class Trim(Func):
7374    arg_types = {
7375        "this": True,
7376        "expression": False,
7377        "position": False,
7378        "collation": False,
7379    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
7382class TsOrDsAdd(Func, TimeUnit):
7383    # return_type is used to correctly cast the arguments of this expression when transpiling it
7384    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
7385
7386    @property
7387    def return_type(self) -> DataType:
7388        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
7386    @property
7387    def return_type(self) -> DataType:
7388        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
7391class TsOrDsDiff(Func, TimeUnit):
7392    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
7395class TsOrDsToDateStr(Func):
7396    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
7399class TsOrDsToDate(Func):
7400    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
7403class TsOrDsToDatetime(Func):
7404    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
7407class TsOrDsToTime(Func):
7408    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
7411class TsOrDsToTimestamp(Func):
7412    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
7415class TsOrDiToDi(Func):
7416    pass
key = 'tsorditodi'
class Unhex(Func):
7419class Unhex(Func):
7420    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7423class Unicode(Func):
7424    pass
key = 'unicode'
class UnixDate(Func):
7428class UnixDate(Func):
7429    pass
key = 'unixdate'
class UnixToStr(Func):
7432class UnixToStr(Func):
7433    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7438class UnixToTime(Func):
7439    arg_types = {
7440        "this": True,
7441        "scale": False,
7442        "zone": False,
7443        "hours": False,
7444        "minutes": False,
7445        "format": False,
7446    }
7447
7448    SECONDS = Literal.number(0)
7449    DECIS = Literal.number(1)
7450    CENTIS = Literal.number(2)
7451    MILLIS = Literal.number(3)
7452    DECIMILLIS = Literal.number(4)
7453    CENTIMILLIS = Literal.number(5)
7454    MICROS = Literal.number(6)
7455    DECIMICROS = Literal.number(7)
7456    CENTIMICROS = Literal.number(8)
7457    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):
7460class UnixToTimeStr(Func):
7461    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7464class UnixSeconds(Func):
7465    pass
key = 'unixseconds'
class UnixMicros(Func):
7468class UnixMicros(Func):
7469    pass
key = 'unixmicros'
class UnixMillis(Func):
7472class UnixMillis(Func):
7473    pass
key = 'unixmillis'
class Uuid(Func):
7476class Uuid(Func):
7477    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7478
7479    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7482class TimestampFromParts(Func):
7483    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7484    arg_types = {
7485        "year": True,
7486        "month": True,
7487        "day": True,
7488        "hour": True,
7489        "min": True,
7490        "sec": True,
7491        "nano": False,
7492        "zone": False,
7493        "milli": False,
7494    }
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):
7497class Upper(Func):
7498    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7501class Corr(Binary, AggFunc):
7502    pass
key = 'corr'
class CumeDist(AggFunc):
7506class CumeDist(AggFunc):
7507    arg_types = {"expressions": False}
7508    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'cumedist'
class Variance(AggFunc):
7511class Variance(AggFunc):
7512    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7515class VariancePop(AggFunc):
7516    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7519class CovarSamp(Binary, AggFunc):
7520    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7523class CovarPop(Binary, AggFunc):
7524    pass
key = 'covarpop'
class Week(Func):
7527class Week(Func):
7528    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class WeekStart(Expression):
7531class WeekStart(Expression):
7532    pass
key = 'weekstart'
class XMLElement(Func):
7535class XMLElement(Func):
7536    _sql_names = ["XMLELEMENT"]
7537    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7540class XMLTable(Func):
7541    arg_types = {
7542        "this": True,
7543        "namespaces": False,
7544        "passing": False,
7545        "columns": False,
7546        "by_ref": False,
7547    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7550class XMLNamespace(Expression):
7551    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7555class XMLKeyValueOption(Expression):
7556    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7559class Year(Func):
7560    pass
key = 'year'
class Use(Expression):
7563class Use(Expression):
7564    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7567class Merge(DML):
7568    arg_types = {
7569        "this": True,
7570        "using": True,
7571        "on": True,
7572        "whens": True,
7573        "with": False,
7574        "returning": False,
7575    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7578class When(Expression):
7579    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):
7582class Whens(Expression):
7583    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7584
7585    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7590class NextValueFor(Func):
7591    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7596class Semicolon(Expression):
7597    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7602class TableColumn(Expression):
7603    pass
key = 'tablecolumn'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'Acos'>, <class 'Acosh'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxQuantiles'>, <class 'ApproxTopK'>, <class 'ApproxTopSum'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConcatAgg'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayFirst'>, <class 'ArrayIntersect'>, <class 'ArrayLast'>, <class 'ArrayOverlaps'>, <class 'ArrayRemove'>, <class 'ArrayReverse'>, <class 'ArraySize'>, <class 'ArraySlice'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Ascii'>, <class 'Asin'>, <class 'Asinh'>, <class 'Atan'>, <class 'Atan2'>, <class 'Atanh'>, <class 'Avg'>, <class 'BitwiseAndAgg'>, <class 'BitwiseCountAgg'>, <class 'BitwiseOrAgg'>, <class 'BitwiseXorAgg'>, <class 'ByteLength'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'CodePointsToBytes'>, <class 'CodePointsToString'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'CosineDistance'>, <class 'Cot'>, <class 'Coth'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'Csc'>, <class 'Csch'>, <class 'CumeDist'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentTimestampLTZ'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateFromUnixDate'>, <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 'DecodeCase'>, <class 'DenseRank'>, <class 'DiToDate'>, <class 'Encode'>, <class 'EndsWith'>, <class 'EuclideanDistance'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FarmFingerprint'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Float64'>, <class 'Floor'>, <class 'Format'>, <class 'FromBase'>, <class 'FromBase32'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateEmbedding'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'GetExtract'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Grouping'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayAppend'>, <class 'JSONArrayContains'>, <class 'JSONArrayInsert'>, <class 'JSONBContains'>, <class 'JSONBContainsAllTopKeys'>, <class 'JSONBContainsAnyTopKeys'>, <class 'JSONBDeleteAtPath'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONBool'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONKeysAtDepth'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONRemove'>, <class 'JSONSet'>, <class 'JSONStripNulls'>, <class 'JSONTable'>, <class 'JSONType'>, <class 'JSONValueArray'>, <class 'JustifyDays'>, <class 'JustifyHours'>, <class 'JustifyInterval'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'LaxBool'>, <class 'LaxFloat64'>, <class 'LaxInt64'>, <class 'LaxString'>, <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 'MLForecast'>, <class 'MLTranslate'>, <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 'Ntile'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseBignumeric'>, <class 'ParseDatetime'>, <class 'ParseJSON'>, <class 'ParseNumeric'>, <class 'ParseTime'>, <class 'PercentRank'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeBucket'>, <class 'RangeN'>, <class 'Rank'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpInstr'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Replace'>, <class 'Reverse'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeAdd'>, <class 'SafeConvertBytesToString'>, <class 'SafeDivide'>, <class 'SafeMultiply'>, <class 'SafeNegate'>, <class 'SafeSubtract'>, <class 'Sec'>, <class 'Sech'>, <class 'Sign'>, <class 'Sin'>, <class 'Sinh'>, <class 'SortArray'>, <class 'Soundex'>, <class 'Space'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StDistance'>, <class 'StPoint'>, <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 'SubstringIndex'>, <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 'ToBase32'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToCodePoints'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Translate'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Typeof'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixMicros'>, <class 'UnixMillis'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'UtcDate'>, <class 'UtcTime'>, <class 'UtcTimestamp'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'VectorSearch'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ACOS': <class 'Acos'>, 'ACOSH': <class 'Acosh'>, '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_QUANTILES': <class 'ApproxQuantiles'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'APPROX_TOP_SUM': <class 'ApproxTopSum'>, '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_CONCAT_AGG': <class 'ArrayConcatAgg'>, '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_FIRST': <class 'ArrayFirst'>, 'ARRAY_INTERSECT': <class 'ArrayIntersect'>, 'ARRAY_INTERSECTION': <class 'ArrayIntersect'>, 'ARRAY_LAST': <class 'ArrayLast'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_REMOVE': <class 'ArrayRemove'>, 'ARRAY_REVERSE': <class 'ArrayReverse'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SLICE': <class 'ArraySlice'>, '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'>, 'ASCII': <class 'Ascii'>, 'ASIN': <class 'Asin'>, 'ASINH': <class 'Asinh'>, 'ATAN': <class 'Atan'>, 'ATAN2': <class 'Atan2'>, 'ATANH': <class 'Atanh'>, 'AVG': <class 'Avg'>, 'BITWISE_AND_AGG': <class 'BitwiseAndAgg'>, 'BITWISE_COUNT_AGG': <class 'BitwiseCountAgg'>, 'BITWISE_OR_AGG': <class 'BitwiseOrAgg'>, 'BITWISE_XOR_AGG': <class 'BitwiseXorAgg'>, 'BYTE_LENGTH': <class 'ByteLength'>, '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'>, 'CODE_POINTS_TO_BYTES': <class 'CodePointsToBytes'>, 'CODE_POINTS_TO_STRING': <class 'CodePointsToString'>, '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'>, 'CONVERT_TO_CHARSET': <class 'ConvertToCharset'>, 'CORR': <class 'Corr'>, 'COSINE_DISTANCE': <class 'CosineDistance'>, 'COT': <class 'Cot'>, 'COTH': <class 'Coth'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CSC': <class 'Csc'>, 'CSCH': <class 'Csch'>, 'CUME_DIST': <class 'CumeDist'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_TIMESTAMP_L_T_Z': <class 'CurrentTimestampLTZ'>, '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_FROM_UNIX_DATE': <class 'DateFromUnixDate'>, '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'>, 'DECODE_CASE': <class 'DecodeCase'>, 'DENSE_RANK': <class 'DenseRank'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'ENDS_WITH': <class 'EndsWith'>, 'ENDSWITH': <class 'EndsWith'>, 'EUCLIDEAN_DISTANCE': <class 'EuclideanDistance'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FARM_FINGERPRINT': <class 'FarmFingerprint'>, 'FARMFINGERPRINT64': <class 'FarmFingerprint'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOAT64': <class 'Float64'>, 'FLOOR': <class 'Floor'>, 'FORMAT': <class 'Format'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE32': <class 'FromBase32'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_EMBEDDING': <class 'GenerateEmbedding'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GET_EXTRACT': <class 'GetExtract'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'GROUPING': <class 'Grouping'>, '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_APPEND': <class 'JSONArrayAppend'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSON_ARRAY_INSERT': <class 'JSONArrayInsert'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'J_S_O_N_B_CONTAINS_ALL_TOP_KEYS': <class 'JSONBContainsAllTopKeys'>, 'J_S_O_N_B_CONTAINS_ANY_TOP_KEYS': <class 'JSONBContainsAnyTopKeys'>, 'J_S_O_N_B_DELETE_AT_PATH': <class 'JSONBDeleteAtPath'>, '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_BOOL': <class 'JSONBool'>, '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_KEYS_AT_DEPTH': <class 'JSONKeysAtDepth'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'JSON_REMOVE': <class 'JSONRemove'>, 'JSON_SET': <class 'JSONSet'>, 'JSON_STRIP_NULLS': <class 'JSONStripNulls'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'JSON_TYPE': <class 'JSONType'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'JUSTIFY_DAYS': <class 'JustifyDays'>, 'JUSTIFY_HOURS': <class 'JustifyHours'>, 'JUSTIFY_INTERVAL': <class 'JustifyInterval'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LAX_BOOL': <class 'LaxBool'>, 'LAX_FLOAT64': <class 'LaxFloat64'>, 'LAX_INT64': <class 'LaxInt64'>, 'LAX_STRING': <class 'LaxString'>, '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'>, 'M_L_FORECAST': <class 'MLForecast'>, 'M_L_TRANSLATE': <class 'MLTranslate'>, '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'>, 'NTILE': <class 'Ntile'>, '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_BIGNUMERIC': <class 'ParseBignumeric'>, 'PARSE_DATETIME': <class 'ParseDatetime'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PARSE_NUMERIC': <class 'ParseNumeric'>, 'PARSE_TIME': <class 'ParseTime'>, 'PERCENT_RANK': <class 'PercentRank'>, '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_BUCKET': <class 'RangeBucket'>, 'RANGE_N': <class 'RangeN'>, 'RANK': <class 'Rank'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_INSTR': <class 'RegexpInstr'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'REPLACE': <class 'Replace'>, 'REVERSE': <class 'Reverse'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_ADD': <class 'SafeAdd'>, 'SAFE_CONVERT_BYTES_TO_STRING': <class 'SafeConvertBytesToString'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SAFE_MULTIPLY': <class 'SafeMultiply'>, 'SAFE_NEGATE': <class 'SafeNegate'>, 'SAFE_SUBTRACT': <class 'SafeSubtract'>, 'SEC': <class 'Sec'>, 'SECH': <class 'Sech'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SIN': <class 'Sin'>, 'SINH': <class 'Sinh'>, 'SORT_ARRAY': <class 'SortArray'>, 'SOUNDEX': <class 'Soundex'>, 'SPACE': <class 'Space'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'ST_DISTANCE': <class 'StDistance'>, 'ST_POINT': <class 'StPoint'>, 'ST_MAKEPOINT': <class 'StPoint'>, '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'>, 'STRTOK_TO_ARRAY': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUBSTRING_INDEX': <class 'SubstringIndex'>, '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_BASE32': <class 'ToBase32'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_CODE_POINTS': <class 'ToCodePoints'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRANSLATE': <class 'Translate'>, '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'>, 'TYPEOF': <class 'Typeof'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_MICROS': <class 'UnixMicros'>, 'UNIX_MILLIS': <class 'UnixMillis'>, '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'>, 'UTC_DATE': <class 'UtcDate'>, 'UTC_TIME': <class 'UtcTime'>, 'UTC_TIMESTAMP': <class 'UtcTimestamp'>, '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'>, 'VECTOR_SEARCH': <class 'VectorSearch'>, '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:
7643def maybe_parse(
7644    sql_or_expression: ExpOrStr,
7645    *,
7646    into: t.Optional[IntoType] = None,
7647    dialect: DialectType = None,
7648    prefix: t.Optional[str] = None,
7649    copy: bool = False,
7650    **opts,
7651) -> Expression:
7652    """Gracefully handle a possible string or expression.
7653
7654    Example:
7655        >>> maybe_parse("1")
7656        Literal(this=1, is_string=False)
7657        >>> maybe_parse(to_identifier("x"))
7658        Identifier(this=x, quoted=False)
7659
7660    Args:
7661        sql_or_expression: the SQL code string or an expression
7662        into: the SQLGlot Expression to parse into
7663        dialect: the dialect used to parse the input expressions (in the case that an
7664            input expression is a SQL string).
7665        prefix: a string to prefix the sql with before it gets parsed
7666            (automatically includes a space)
7667        copy: whether to copy the expression.
7668        **opts: other options to use to parse the input expressions (again, in the case
7669            that an input expression is a SQL string).
7670
7671    Returns:
7672        Expression: the parsed or given expression.
7673    """
7674    if isinstance(sql_or_expression, Expression):
7675        if copy:
7676            return sql_or_expression.copy()
7677        return sql_or_expression
7678
7679    if sql_or_expression is None:
7680        raise ParseError("SQL cannot be None")
7681
7682    import sqlglot
7683
7684    sql = str(sql_or_expression)
7685    if prefix:
7686        sql = f"{prefix} {sql}"
7687
7688    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):
7699def maybe_copy(instance, copy=True):
7700    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:
7955def union(
7956    *expressions: ExpOrStr,
7957    distinct: bool = True,
7958    dialect: DialectType = None,
7959    copy: bool = True,
7960    **opts,
7961) -> Union:
7962    """
7963    Initializes a syntax tree for the `UNION` operation.
7964
7965    Example:
7966        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7967        'SELECT * FROM foo UNION SELECT * FROM bla'
7968
7969    Args:
7970        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7971            If `Expression` instances are passed, they will be used as-is.
7972        distinct: set the DISTINCT flag if and only if this is true.
7973        dialect: the dialect used to parse the input expression.
7974        copy: whether to copy the expression.
7975        opts: other options to use to parse the input expressions.
7976
7977    Returns:
7978        The new Union instance.
7979    """
7980    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7981    return _apply_set_operation(
7982        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7983    )

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:
7986def intersect(
7987    *expressions: ExpOrStr,
7988    distinct: bool = True,
7989    dialect: DialectType = None,
7990    copy: bool = True,
7991    **opts,
7992) -> Intersect:
7993    """
7994    Initializes a syntax tree for the `INTERSECT` operation.
7995
7996    Example:
7997        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7998        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7999
8000    Args:
8001        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
8002            If `Expression` instances are passed, they will be used as-is.
8003        distinct: set the DISTINCT flag if and only if this is true.
8004        dialect: the dialect used to parse the input expression.
8005        copy: whether to copy the expression.
8006        opts: other options to use to parse the input expressions.
8007
8008    Returns:
8009        The new Intersect instance.
8010    """
8011    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
8012    return _apply_set_operation(
8013        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
8014    )

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:
8017def except_(
8018    *expressions: ExpOrStr,
8019    distinct: bool = True,
8020    dialect: DialectType = None,
8021    copy: bool = True,
8022    **opts,
8023) -> Except:
8024    """
8025    Initializes a syntax tree for the `EXCEPT` operation.
8026
8027    Example:
8028        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
8029        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
8030
8031    Args:
8032        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
8033            If `Expression` instances are passed, they will be used as-is.
8034        distinct: set the DISTINCT flag if and only if this is true.
8035        dialect: the dialect used to parse the input expression.
8036        copy: whether to copy the expression.
8037        opts: other options to use to parse the input expressions.
8038
8039    Returns:
8040        The new Except instance.
8041    """
8042    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
8043    return _apply_set_operation(
8044        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
8045    )

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:
8048def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
8049    """
8050    Initializes a syntax tree from one or multiple SELECT expressions.
8051
8052    Example:
8053        >>> select("col1", "col2").from_("tbl").sql()
8054        'SELECT col1, col2 FROM tbl'
8055
8056    Args:
8057        *expressions: the SQL code string to parse as the expressions of a
8058            SELECT statement. If an Expression instance is passed, this is used as-is.
8059        dialect: the dialect used to parse the input expressions (in the case that an
8060            input expression is a SQL string).
8061        **opts: other options to use to parse the input expressions (again, in the case
8062            that an input expression is a SQL string).
8063
8064    Returns:
8065        Select: the syntax tree for the SELECT statement.
8066    """
8067    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:
8070def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
8071    """
8072    Initializes a syntax tree from a FROM expression.
8073
8074    Example:
8075        >>> from_("tbl").select("col1", "col2").sql()
8076        'SELECT col1, col2 FROM tbl'
8077
8078    Args:
8079        *expression: the SQL code string to parse as the FROM expressions of a
8080            SELECT statement. If an Expression instance is passed, this is used as-is.
8081        dialect: the dialect used to parse the input expression (in the case that the
8082            input expression is a SQL string).
8083        **opts: other options to use to parse the input expressions (again, in the case
8084            that the input expression is a SQL string).
8085
8086    Returns:
8087        Select: the syntax tree for the SELECT statement.
8088    """
8089    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:
8092def update(
8093    table: str | Table,
8094    properties: t.Optional[dict] = None,
8095    where: t.Optional[ExpOrStr] = None,
8096    from_: t.Optional[ExpOrStr] = None,
8097    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
8098    dialect: DialectType = None,
8099    **opts,
8100) -> Update:
8101    """
8102    Creates an update statement.
8103
8104    Example:
8105        >>> 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()
8106        "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"
8107
8108    Args:
8109        properties: dictionary of properties to SET which are
8110            auto converted to sql objects eg None -> NULL
8111        where: sql conditional parsed into a WHERE statement
8112        from_: sql statement parsed into a FROM statement
8113        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
8114        dialect: the dialect used to parse the input expressions.
8115        **opts: other options to use to parse the input expressions.
8116
8117    Returns:
8118        Update: the syntax tree for the UPDATE statement.
8119    """
8120    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
8121    if properties:
8122        update_expr.set(
8123            "expressions",
8124            [
8125                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
8126                for k, v in properties.items()
8127            ],
8128        )
8129    if from_:
8130        update_expr.set(
8131            "from",
8132            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
8133        )
8134    if isinstance(where, Condition):
8135        where = Where(this=where)
8136    if where:
8137        update_expr.set(
8138            "where",
8139            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
8140        )
8141    if with_:
8142        cte_list = [
8143            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
8144            for alias, qry in with_.items()
8145        ]
8146        update_expr.set(
8147            "with",
8148            With(expressions=cte_list),
8149        )
8150    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:
8153def delete(
8154    table: ExpOrStr,
8155    where: t.Optional[ExpOrStr] = None,
8156    returning: t.Optional[ExpOrStr] = None,
8157    dialect: DialectType = None,
8158    **opts,
8159) -> Delete:
8160    """
8161    Builds a delete statement.
8162
8163    Example:
8164        >>> delete("my_table", where="id > 1").sql()
8165        'DELETE FROM my_table WHERE id > 1'
8166
8167    Args:
8168        where: sql conditional parsed into a WHERE statement
8169        returning: sql conditional parsed into a RETURNING statement
8170        dialect: the dialect used to parse the input expressions.
8171        **opts: other options to use to parse the input expressions.
8172
8173    Returns:
8174        Delete: the syntax tree for the DELETE statement.
8175    """
8176    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
8177    if where:
8178        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
8179    if returning:
8180        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
8181    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:
8184def insert(
8185    expression: ExpOrStr,
8186    into: ExpOrStr,
8187    columns: t.Optional[t.Sequence[str | Identifier]] = None,
8188    overwrite: t.Optional[bool] = None,
8189    returning: t.Optional[ExpOrStr] = None,
8190    dialect: DialectType = None,
8191    copy: bool = True,
8192    **opts,
8193) -> Insert:
8194    """
8195    Builds an INSERT statement.
8196
8197    Example:
8198        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
8199        'INSERT INTO tbl VALUES (1, 2, 3)'
8200
8201    Args:
8202        expression: the sql string or expression of the INSERT statement
8203        into: the tbl to insert data to.
8204        columns: optionally the table's column names.
8205        overwrite: whether to INSERT OVERWRITE or not.
8206        returning: sql conditional parsed into a RETURNING statement
8207        dialect: the dialect used to parse the input expressions.
8208        copy: whether to copy the expression.
8209        **opts: other options to use to parse the input expressions.
8210
8211    Returns:
8212        Insert: the syntax tree for the INSERT statement.
8213    """
8214    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8215    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
8216
8217    if columns:
8218        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
8219
8220    insert = Insert(this=this, expression=expr, overwrite=overwrite)
8221
8222    if returning:
8223        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
8224
8225    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:
8228def merge(
8229    *when_exprs: ExpOrStr,
8230    into: ExpOrStr,
8231    using: ExpOrStr,
8232    on: ExpOrStr,
8233    returning: t.Optional[ExpOrStr] = None,
8234    dialect: DialectType = None,
8235    copy: bool = True,
8236    **opts,
8237) -> Merge:
8238    """
8239    Builds a MERGE statement.
8240
8241    Example:
8242        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
8243        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
8244        ...       into="my_table",
8245        ...       using="source_table",
8246        ...       on="my_table.id = source_table.id").sql()
8247        '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)'
8248
8249    Args:
8250        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
8251        into: The target table to merge data into.
8252        using: The source table to merge data from.
8253        on: The join condition for the merge.
8254        returning: The columns to return from the merge.
8255        dialect: The dialect used to parse the input expressions.
8256        copy: Whether to copy the expression.
8257        **opts: Other options to use to parse the input expressions.
8258
8259    Returns:
8260        Merge: The syntax tree for the MERGE statement.
8261    """
8262    expressions: t.List[Expression] = []
8263    for when_expr in when_exprs:
8264        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
8265        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
8266
8267    merge = Merge(
8268        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
8269        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
8270        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
8271        whens=Whens(expressions=expressions),
8272    )
8273    if returning:
8274        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
8275
8276    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:
8279def condition(
8280    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
8281) -> Condition:
8282    """
8283    Initialize a logical condition expression.
8284
8285    Example:
8286        >>> condition("x=1").sql()
8287        'x = 1'
8288
8289        This is helpful for composing larger logical syntax trees:
8290        >>> where = condition("x=1")
8291        >>> where = where.and_("y=1")
8292        >>> Select().from_("tbl").select("*").where(where).sql()
8293        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
8294
8295    Args:
8296        *expression: the SQL code string to parse.
8297            If an Expression instance is passed, this is used as-is.
8298        dialect: the dialect used to parse the input expression (in the case that the
8299            input expression is a SQL string).
8300        copy: Whether to copy `expression` (only applies to expressions).
8301        **opts: other options to use to parse the input expressions (again, in the case
8302            that the input expression is a SQL string).
8303
8304    Returns:
8305        The new Condition instance
8306    """
8307    return maybe_parse(
8308        expression,
8309        into=Condition,
8310        dialect=dialect,
8311        copy=copy,
8312        **opts,
8313    )

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:
8316def and_(
8317    *expressions: t.Optional[ExpOrStr],
8318    dialect: DialectType = None,
8319    copy: bool = True,
8320    wrap: bool = True,
8321    **opts,
8322) -> Condition:
8323    """
8324    Combine multiple conditions with an AND logical operator.
8325
8326    Example:
8327        >>> and_("x=1", and_("y=1", "z=1")).sql()
8328        'x = 1 AND (y = 1 AND z = 1)'
8329
8330    Args:
8331        *expressions: the SQL code strings to parse.
8332            If an Expression instance is passed, this is used as-is.
8333        dialect: the dialect used to parse the input expression.
8334        copy: whether to copy `expressions` (only applies to Expressions).
8335        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8336            precedence issues, but can be turned off when the produced AST is too deep and
8337            causes recursion-related issues.
8338        **opts: other options to use to parse the input expressions.
8339
8340    Returns:
8341        The new condition
8342    """
8343    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:
8346def or_(
8347    *expressions: t.Optional[ExpOrStr],
8348    dialect: DialectType = None,
8349    copy: bool = True,
8350    wrap: bool = True,
8351    **opts,
8352) -> Condition:
8353    """
8354    Combine multiple conditions with an OR logical operator.
8355
8356    Example:
8357        >>> or_("x=1", or_("y=1", "z=1")).sql()
8358        'x = 1 OR (y = 1 OR z = 1)'
8359
8360    Args:
8361        *expressions: the SQL code strings to parse.
8362            If an Expression instance is passed, this is used as-is.
8363        dialect: the dialect used to parse the input expression.
8364        copy: whether to copy `expressions` (only applies to Expressions).
8365        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8366            precedence issues, but can be turned off when the produced AST is too deep and
8367            causes recursion-related issues.
8368        **opts: other options to use to parse the input expressions.
8369
8370    Returns:
8371        The new condition
8372    """
8373    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:
8376def xor(
8377    *expressions: t.Optional[ExpOrStr],
8378    dialect: DialectType = None,
8379    copy: bool = True,
8380    wrap: bool = True,
8381    **opts,
8382) -> Condition:
8383    """
8384    Combine multiple conditions with an XOR logical operator.
8385
8386    Example:
8387        >>> xor("x=1", xor("y=1", "z=1")).sql()
8388        'x = 1 XOR (y = 1 XOR z = 1)'
8389
8390    Args:
8391        *expressions: the SQL code strings to parse.
8392            If an Expression instance is passed, this is used as-is.
8393        dialect: the dialect used to parse the input expression.
8394        copy: whether to copy `expressions` (only applies to Expressions).
8395        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8396            precedence issues, but can be turned off when the produced AST is too deep and
8397            causes recursion-related issues.
8398        **opts: other options to use to parse the input expressions.
8399
8400    Returns:
8401        The new condition
8402    """
8403    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:
8406def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
8407    """
8408    Wrap a condition with a NOT operator.
8409
8410    Example:
8411        >>> not_("this_suit='black'").sql()
8412        "NOT this_suit = 'black'"
8413
8414    Args:
8415        expression: the SQL code string to parse.
8416            If an Expression instance is passed, this is used as-is.
8417        dialect: the dialect used to parse the input expression.
8418        copy: whether to copy the expression or not.
8419        **opts: other options to use to parse the input expressions.
8420
8421    Returns:
8422        The new condition.
8423    """
8424    this = condition(
8425        expression,
8426        dialect=dialect,
8427        copy=copy,
8428        **opts,
8429    )
8430    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:
8433def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
8434    """
8435    Wrap an expression in parentheses.
8436
8437    Example:
8438        >>> paren("5 + 3").sql()
8439        '(5 + 3)'
8440
8441    Args:
8442        expression: the SQL code string to parse.
8443            If an Expression instance is passed, this is used as-is.
8444        copy: whether to copy the expression or not.
8445
8446    Returns:
8447        The wrapped expression.
8448    """
8449    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):
8465def to_identifier(name, quoted=None, copy=True):
8466    """Builds an identifier.
8467
8468    Args:
8469        name: The name to turn into an identifier.
8470        quoted: Whether to force quote the identifier.
8471        copy: Whether to copy name if it's an Identifier.
8472
8473    Returns:
8474        The identifier ast node.
8475    """
8476
8477    if name is None:
8478        return None
8479
8480    if isinstance(name, Identifier):
8481        identifier = maybe_copy(name, copy)
8482    elif isinstance(name, str):
8483        identifier = Identifier(
8484            this=name,
8485            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8486        )
8487    else:
8488        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8489    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:
8492def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8493    """
8494    Parses a given string into an identifier.
8495
8496    Args:
8497        name: The name to parse into an identifier.
8498        dialect: The dialect to parse against.
8499
8500    Returns:
8501        The identifier ast node.
8502    """
8503    try:
8504        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8505    except (ParseError, TokenError):
8506        expression = to_identifier(name)
8507
8508    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]+(?:\\.[0-9]+)?)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
8514def to_interval(interval: str | Literal) -> Interval:
8515    """Builds an interval expression from a string like '1 day' or '5 months'."""
8516    if isinstance(interval, Literal):
8517        if not interval.is_string:
8518            raise ValueError("Invalid interval string.")
8519
8520        interval = interval.this
8521
8522    interval = maybe_parse(f"INTERVAL {interval}")
8523    assert isinstance(interval, Interval)
8524    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:
8527def to_table(
8528    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8529) -> Table:
8530    """
8531    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8532    If a table is passed in then that table is returned.
8533
8534    Args:
8535        sql_path: a `[catalog].[schema].[table]` string.
8536        dialect: the source dialect according to which the table name will be parsed.
8537        copy: Whether to copy a table if it is passed in.
8538        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8539
8540    Returns:
8541        A table expression.
8542    """
8543    if isinstance(sql_path, Table):
8544        return maybe_copy(sql_path, copy=copy)
8545
8546    try:
8547        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8548    except ParseError:
8549        catalog, db, this = split_num_words(sql_path, ".", 3)
8550
8551        if not this:
8552            raise
8553
8554        table = table_(this, db=db, catalog=catalog)
8555
8556    for k, v in kwargs.items():
8557        table.set(k, v)
8558
8559    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:
8562def to_column(
8563    sql_path: str | Column,
8564    quoted: t.Optional[bool] = None,
8565    dialect: DialectType = None,
8566    copy: bool = True,
8567    **kwargs,
8568) -> Column:
8569    """
8570    Create a column from a `[table].[column]` sql path. Table is optional.
8571    If a column is passed in then that column is returned.
8572
8573    Args:
8574        sql_path: a `[table].[column]` string.
8575        quoted: Whether or not to force quote identifiers.
8576        dialect: the source dialect according to which the column name will be parsed.
8577        copy: Whether to copy a column if it is passed in.
8578        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8579
8580    Returns:
8581        A column expression.
8582    """
8583    if isinstance(sql_path, Column):
8584        return maybe_copy(sql_path, copy=copy)
8585
8586    try:
8587        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8588    except ParseError:
8589        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8590
8591    for k, v in kwargs.items():
8592        col.set(k, v)
8593
8594    if quoted:
8595        for i in col.find_all(Identifier):
8596            i.set("quoted", True)
8597
8598    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):
8601def alias_(
8602    expression: ExpOrStr,
8603    alias: t.Optional[str | Identifier],
8604    table: bool | t.Sequence[str | Identifier] = False,
8605    quoted: t.Optional[bool] = None,
8606    dialect: DialectType = None,
8607    copy: bool = True,
8608    **opts,
8609):
8610    """Create an Alias expression.
8611
8612    Example:
8613        >>> alias_('foo', 'bar').sql()
8614        'foo AS bar'
8615
8616        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8617        '(SELECT 1, 2) AS bar(a, b)'
8618
8619    Args:
8620        expression: the SQL code strings to parse.
8621            If an Expression instance is passed, this is used as-is.
8622        alias: the alias name to use. If the name has
8623            special characters it is quoted.
8624        table: Whether to create a table alias, can also be a list of columns.
8625        quoted: whether to quote the alias
8626        dialect: the dialect used to parse the input expression.
8627        copy: Whether to copy the expression.
8628        **opts: other options to use to parse the input expressions.
8629
8630    Returns:
8631        Alias: the aliased expression
8632    """
8633    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8634    alias = to_identifier(alias, quoted=quoted)
8635
8636    if table:
8637        table_alias = TableAlias(this=alias)
8638        exp.set("alias", table_alias)
8639
8640        if not isinstance(table, bool):
8641            for column in table:
8642                table_alias.append("columns", to_identifier(column, quoted=quoted))
8643
8644        return exp
8645
8646    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8647    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8648    # for the complete Window expression.
8649    #
8650    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8651
8652    if "alias" in exp.arg_types and not isinstance(exp, Window):
8653        exp.set("alias", alias)
8654        return exp
8655    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:
8658def subquery(
8659    expression: ExpOrStr,
8660    alias: t.Optional[Identifier | str] = None,
8661    dialect: DialectType = None,
8662    **opts,
8663) -> Select:
8664    """
8665    Build a subquery expression that's selected from.
8666
8667    Example:
8668        >>> subquery('select x from tbl', 'bar').select('x').sql()
8669        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8670
8671    Args:
8672        expression: the SQL code strings to parse.
8673            If an Expression instance is passed, this is used as-is.
8674        alias: the alias name to use.
8675        dialect: the dialect used to parse the input expression.
8676        **opts: other options to use to parse the input expressions.
8677
8678    Returns:
8679        A new Select instance with the subquery expression included.
8680    """
8681
8682    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8683    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):
8714def column(
8715    col,
8716    table=None,
8717    db=None,
8718    catalog=None,
8719    *,
8720    fields=None,
8721    quoted=None,
8722    copy=True,
8723):
8724    """
8725    Build a Column.
8726
8727    Args:
8728        col: Column name.
8729        table: Table name.
8730        db: Database name.
8731        catalog: Catalog name.
8732        fields: Additional fields using dots.
8733        quoted: Whether to force quotes on the column's identifiers.
8734        copy: Whether to copy identifiers if passed in.
8735
8736    Returns:
8737        The new Column instance.
8738    """
8739    if not isinstance(col, Star):
8740        col = to_identifier(col, quoted=quoted, copy=copy)
8741
8742    this = Column(
8743        this=col,
8744        table=to_identifier(table, quoted=quoted, copy=copy),
8745        db=to_identifier(db, quoted=quoted, copy=copy),
8746        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8747    )
8748
8749    if fields:
8750        this = Dot.build(
8751            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8752        )
8753    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, Identifier, Dot, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8756def cast(
8757    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8758) -> Cast:
8759    """Cast an expression to a data type.
8760
8761    Example:
8762        >>> cast('x + 1', 'int').sql()
8763        'CAST(x + 1 AS INT)'
8764
8765    Args:
8766        expression: The expression to cast.
8767        to: The datatype to cast to.
8768        copy: Whether to copy the supplied expressions.
8769        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8770            - The expression to be cast is already a exp.Cast expression
8771            - The existing cast is to a type that is logically equivalent to new type
8772
8773            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8774            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8775            and instead just return the original expression `CAST(x as DATETIME)`.
8776
8777            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8778            mapping is applied in the target dialect generator.
8779
8780    Returns:
8781        The new Cast instance.
8782    """
8783    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8784    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8785
8786    # dont re-cast if the expression is already a cast to the correct type
8787    if isinstance(expr, Cast):
8788        from sqlglot.dialects.dialect import Dialect
8789
8790        target_dialect = Dialect.get_or_raise(dialect)
8791        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8792
8793        existing_cast_type: DataType.Type = expr.to.this
8794        new_cast_type: DataType.Type = data_type.this
8795        types_are_equivalent = type_mapping.get(
8796            existing_cast_type, existing_cast_type.value
8797        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8798
8799        if expr.is_type(data_type) or types_are_equivalent:
8800            return expr
8801
8802    expr = Cast(this=expr, to=data_type)
8803    expr.type = data_type
8804
8805    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:
8808def table_(
8809    table: Identifier | str,
8810    db: t.Optional[Identifier | str] = None,
8811    catalog: t.Optional[Identifier | str] = None,
8812    quoted: t.Optional[bool] = None,
8813    alias: t.Optional[Identifier | str] = None,
8814) -> Table:
8815    """Build a Table.
8816
8817    Args:
8818        table: Table name.
8819        db: Database name.
8820        catalog: Catalog name.
8821        quote: Whether to force quotes on the table's identifiers.
8822        alias: Table's alias.
8823
8824    Returns:
8825        The new Table instance.
8826    """
8827    return Table(
8828        this=to_identifier(table, quoted=quoted) if table else None,
8829        db=to_identifier(db, quoted=quoted) if db else None,
8830        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8831        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8832    )

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:
8835def values(
8836    values: t.Iterable[t.Tuple[t.Any, ...]],
8837    alias: t.Optional[str] = None,
8838    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8839) -> Values:
8840    """Build VALUES statement.
8841
8842    Example:
8843        >>> values([(1, '2')]).sql()
8844        "VALUES (1, '2')"
8845
8846    Args:
8847        values: values statements that will be converted to SQL
8848        alias: optional alias
8849        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8850         If either are provided then an alias is also required.
8851
8852    Returns:
8853        Values: the Values expression object
8854    """
8855    if columns and not alias:
8856        raise ValueError("Alias is required when providing columns")
8857
8858    return Values(
8859        expressions=[convert(tup) for tup in values],
8860        alias=(
8861            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8862            if columns
8863            else (TableAlias(this=to_identifier(alias)) if alias else None)
8864        ),
8865    )

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:
8868def var(name: t.Optional[ExpOrStr]) -> Var:
8869    """Build a SQL variable.
8870
8871    Example:
8872        >>> repr(var('x'))
8873        'Var(this=x)'
8874
8875        >>> repr(var(column('x', table='y')))
8876        'Var(this=x)'
8877
8878    Args:
8879        name: The name of the var or an expression who's name will become the var.
8880
8881    Returns:
8882        The new variable node.
8883    """
8884    if not name:
8885        raise ValueError("Cannot convert empty name into var.")
8886
8887    if isinstance(name, Expression):
8888        name = name.name
8889    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:
8892def rename_table(
8893    old_name: str | Table,
8894    new_name: str | Table,
8895    dialect: DialectType = None,
8896) -> Alter:
8897    """Build ALTER TABLE... RENAME... expression
8898
8899    Args:
8900        old_name: The old name of the table
8901        new_name: The new name of the table
8902        dialect: The dialect to parse the table.
8903
8904    Returns:
8905        Alter table expression
8906    """
8907    old_table = to_table(old_name, dialect=dialect)
8908    new_table = to_table(new_name, dialect=dialect)
8909    return Alter(
8910        this=old_table,
8911        kind="TABLE",
8912        actions=[
8913            AlterRename(this=new_table),
8914        ],
8915    )

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:
8918def rename_column(
8919    table_name: str | Table,
8920    old_column_name: str | Column,
8921    new_column_name: str | Column,
8922    exists: t.Optional[bool] = None,
8923    dialect: DialectType = None,
8924) -> Alter:
8925    """Build ALTER TABLE... RENAME COLUMN... expression
8926
8927    Args:
8928        table_name: Name of the table
8929        old_column: The old name of the column
8930        new_column: The new name of the column
8931        exists: Whether to add the `IF EXISTS` clause
8932        dialect: The dialect to parse the table/column.
8933
8934    Returns:
8935        Alter table expression
8936    """
8937    table = to_table(table_name, dialect=dialect)
8938    old_column = to_column(old_column_name, dialect=dialect)
8939    new_column = to_column(new_column_name, dialect=dialect)
8940    return Alter(
8941        this=table,
8942        kind="TABLE",
8943        actions=[
8944            RenameColumn(this=old_column, to=new_column, exists=exists),
8945        ],
8946    )

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:
8949def convert(value: t.Any, copy: bool = False) -> Expression:
8950    """Convert a python value into an expression object.
8951
8952    Raises an error if a conversion is not possible.
8953
8954    Args:
8955        value: A python object.
8956        copy: Whether to copy `value` (only applies to Expressions and collections).
8957
8958    Returns:
8959        The equivalent expression object.
8960    """
8961    if isinstance(value, Expression):
8962        return maybe_copy(value, copy)
8963    if isinstance(value, str):
8964        return Literal.string(value)
8965    if isinstance(value, bool):
8966        return Boolean(this=value)
8967    if value is None or (isinstance(value, float) and math.isnan(value)):
8968        return null()
8969    if isinstance(value, numbers.Number):
8970        return Literal.number(value)
8971    if isinstance(value, bytes):
8972        return HexString(this=value.hex())
8973    if isinstance(value, datetime.datetime):
8974        datetime_literal = Literal.string(value.isoformat(sep=" "))
8975
8976        tz = None
8977        if value.tzinfo:
8978            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8979            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8980            tz = Literal.string(str(value.tzinfo))
8981
8982        return TimeStrToTime(this=datetime_literal, zone=tz)
8983    if isinstance(value, datetime.date):
8984        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8985        return DateStrToDate(this=date_literal)
8986    if isinstance(value, datetime.time):
8987        time_literal = Literal.string(value.isoformat())
8988        return TsOrDsToTime(this=time_literal)
8989    if isinstance(value, tuple):
8990        if hasattr(value, "_fields"):
8991            return Struct(
8992                expressions=[
8993                    PropertyEQ(
8994                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8995                    )
8996                    for k in value._fields
8997                ]
8998            )
8999        return Tuple(expressions=[convert(v, copy=copy) for v in value])
9000    if isinstance(value, list):
9001        return Array(expressions=[convert(v, copy=copy) for v in value])
9002    if isinstance(value, dict):
9003        return Map(
9004            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
9005            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
9006        )
9007    if hasattr(value, "__dict__"):
9008        return Struct(
9009            expressions=[
9010                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
9011                for k, v in value.__dict__.items()
9012            ]
9013        )
9014    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:
9017def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
9018    """
9019    Replace children of an expression with the result of a lambda fun(child) -> exp.
9020    """
9021    for k, v in tuple(expression.args.items()):
9022        is_list_arg = type(v) is list
9023
9024        child_nodes = v if is_list_arg else [v]
9025        new_child_nodes = []
9026
9027        for cn in child_nodes:
9028            if isinstance(cn, Expression):
9029                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
9030                    new_child_nodes.append(child_node)
9031            else:
9032                new_child_nodes.append(cn)
9033
9034        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:
9037def replace_tree(
9038    expression: Expression,
9039    fun: t.Callable,
9040    prune: t.Optional[t.Callable[[Expression], bool]] = None,
9041) -> Expression:
9042    """
9043    Replace an entire tree with the result of function calls on each node.
9044
9045    This will be traversed in reverse dfs, so leaves first.
9046    If new nodes are created as a result of function calls, they will also be traversed.
9047    """
9048    stack = list(expression.dfs(prune=prune))
9049
9050    while stack:
9051        node = stack.pop()
9052        new_node = fun(node)
9053
9054        if new_node is not node:
9055            node.replace(new_node)
9056
9057            if isinstance(new_node, Expression):
9058                stack.append(new_node)
9059
9060    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]:
9063def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
9064    """
9065    Return all table names referenced through columns in an expression.
9066
9067    Example:
9068        >>> import sqlglot
9069        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
9070        ['a', 'c']
9071
9072    Args:
9073        expression: expression to find table names.
9074        exclude: a table name to exclude
9075
9076    Returns:
9077        A list of unique names.
9078    """
9079    return {
9080        table
9081        for table in (column.table for column in expression.find_all(Column))
9082        if table and table != exclude
9083    }

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:
9086def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
9087    """Get the full name of a table as a string.
9088
9089    Args:
9090        table: Table expression node or string.
9091        dialect: The dialect to generate the table name for.
9092        identify: Determines when an identifier should be quoted. Possible values are:
9093            False (default): Never quote, except in cases where it's mandatory by the dialect.
9094            True: Always quote.
9095
9096    Examples:
9097        >>> from sqlglot import exp, parse_one
9098        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
9099        'a.b.c'
9100
9101    Returns:
9102        The table name.
9103    """
9104
9105    table = maybe_parse(table, into=Table, dialect=dialect)
9106
9107    if not table:
9108        raise ValueError(f"Cannot parse {table}")
9109
9110    return ".".join(
9111        (
9112            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
9113            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
9114            else part.name
9115        )
9116        for part in table.parts
9117    )

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:
9120def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
9121    """Returns a case normalized table name without quotes.
9122
9123    Args:
9124        table: the table to normalize
9125        dialect: the dialect to use for normalization rules
9126        copy: whether to copy the expression.
9127
9128    Examples:
9129        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
9130        'A-B.c'
9131    """
9132    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
9133
9134    return ".".join(
9135        p.name
9136        for p in normalize_identifiers(
9137            to_table(table, dialect=dialect, copy=copy), dialect=dialect
9138        ).parts
9139    )

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:
9142def replace_tables(
9143    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
9144) -> E:
9145    """Replace all tables in expression according to the mapping.
9146
9147    Args:
9148        expression: expression node to be transformed and replaced.
9149        mapping: mapping of table names.
9150        dialect: the dialect of the mapping table
9151        copy: whether to copy the expression.
9152
9153    Examples:
9154        >>> from sqlglot import exp, parse_one
9155        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
9156        'SELECT * FROM c /* a.b */'
9157
9158    Returns:
9159        The mapped expression.
9160    """
9161
9162    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
9163
9164    def _replace_tables(node: Expression) -> Expression:
9165        if isinstance(node, Table) and node.meta.get("replace") is not False:
9166            original = normalize_table_name(node, dialect=dialect)
9167            new_name = mapping.get(original)
9168
9169            if new_name:
9170                table = to_table(
9171                    new_name,
9172                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
9173                    dialect=dialect,
9174                )
9175                table.add_comments([original])
9176                return table
9177        return node
9178
9179    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:
9182def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
9183    """Replace placeholders in an expression.
9184
9185    Args:
9186        expression: expression node to be transformed and replaced.
9187        args: positional names that will substitute unnamed placeholders in the given order.
9188        kwargs: keyword arguments that will substitute named placeholders.
9189
9190    Examples:
9191        >>> from sqlglot import exp, parse_one
9192        >>> replace_placeholders(
9193        ...     parse_one("select * from :tbl where ? = ?"),
9194        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
9195        ... ).sql()
9196        "SELECT * FROM foo WHERE str_col = 'b'"
9197
9198    Returns:
9199        The mapped expression.
9200    """
9201
9202    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
9203        if isinstance(node, Placeholder):
9204            if node.this:
9205                new_name = kwargs.get(node.this)
9206                if new_name is not None:
9207                    return convert(new_name)
9208            else:
9209                try:
9210                    return convert(next(args))
9211                except StopIteration:
9212                    pass
9213        return node
9214
9215    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:
9218def expand(
9219    expression: Expression,
9220    sources: t.Dict[str, Query | t.Callable[[], Query]],
9221    dialect: DialectType = None,
9222    copy: bool = True,
9223) -> Expression:
9224    """Transforms an expression by expanding all referenced sources into subqueries.
9225
9226    Examples:
9227        >>> from sqlglot import parse_one
9228        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
9229        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
9230
9231        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
9232        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
9233
9234    Args:
9235        expression: The expression to expand.
9236        sources: A dict of name to query or a callable that provides a query on demand.
9237        dialect: The dialect of the sources dict or the callable.
9238        copy: Whether to copy the expression during transformation. Defaults to True.
9239
9240    Returns:
9241        The transformed expression.
9242    """
9243    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
9244
9245    def _expand(node: Expression):
9246        if isinstance(node, Table):
9247            name = normalize_table_name(node, dialect=dialect)
9248            source = normalized_sources.get(name)
9249
9250            if source:
9251                # Create a subquery with the same alias (or table name if no alias)
9252                parsed_source = source() if callable(source) else source
9253                subquery = parsed_source.subquery(node.alias or name)
9254                subquery.comments = [f"source: {name}"]
9255
9256                # Continue expanding within the subquery
9257                return subquery.transform(_expand, copy=False)
9258
9259        return node
9260
9261    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:
9264def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
9265    """
9266    Returns a Func expression.
9267
9268    Examples:
9269        >>> func("abs", 5).sql()
9270        'ABS(5)'
9271
9272        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
9273        'CAST(5 AS DOUBLE)'
9274
9275    Args:
9276        name: the name of the function to build.
9277        args: the args used to instantiate the function of interest.
9278        copy: whether to copy the argument expressions.
9279        dialect: the source dialect.
9280        kwargs: the kwargs used to instantiate the function of interest.
9281
9282    Note:
9283        The arguments `args` and `kwargs` are mutually exclusive.
9284
9285    Returns:
9286        An instance of the function of interest, or an anonymous function, if `name` doesn't
9287        correspond to an existing `sqlglot.expressions.Func` class.
9288    """
9289    if args and kwargs:
9290        raise ValueError("Can't use both args and kwargs to instantiate a function.")
9291
9292    from sqlglot.dialects.dialect import Dialect
9293
9294    dialect = Dialect.get_or_raise(dialect)
9295
9296    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
9297    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
9298
9299    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
9300    if constructor:
9301        if converted:
9302            if "dialect" in constructor.__code__.co_varnames:
9303                function = constructor(converted, dialect=dialect)
9304            else:
9305                function = constructor(converted)
9306        elif constructor.__name__ == "from_arg_list":
9307            function = constructor.__self__(**kwargs)  # type: ignore
9308        else:
9309            constructor = FUNCTION_BY_NAME.get(name.upper())
9310            if constructor:
9311                function = constructor(**kwargs)
9312            else:
9313                raise ValueError(
9314                    f"Unable to convert '{name}' into a Func. Either manually construct "
9315                    "the Func expression of interest or parse the function call."
9316                )
9317    else:
9318        kwargs = kwargs or {"expressions": converted}
9319        function = Anonymous(this=name, **kwargs)
9320
9321    for error_message in function.error_messages(converted):
9322        raise ValueError(error_message)
9323
9324    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:
9327def case(
9328    expression: t.Optional[ExpOrStr] = None,
9329    **opts,
9330) -> Case:
9331    """
9332    Initialize a CASE statement.
9333
9334    Example:
9335        case().when("a = 1", "foo").else_("bar")
9336
9337    Args:
9338        expression: Optionally, the input expression (not all dialects support this)
9339        **opts: Extra keyword arguments for parsing `expression`
9340    """
9341    if expression is not None:
9342        this = maybe_parse(expression, **opts)
9343    else:
9344        this = None
9345    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:
9348def array(
9349    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9350) -> Array:
9351    """
9352    Returns an array.
9353
9354    Examples:
9355        >>> array(1, 'x').sql()
9356        'ARRAY(1, x)'
9357
9358    Args:
9359        expressions: the expressions to add to the array.
9360        copy: whether to copy the argument expressions.
9361        dialect: the source dialect.
9362        kwargs: the kwargs used to instantiate the function of interest.
9363
9364    Returns:
9365        An array expression.
9366    """
9367    return Array(
9368        expressions=[
9369            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9370            for expression in expressions
9371        ]
9372    )

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:
9375def tuple_(
9376    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9377) -> Tuple:
9378    """
9379    Returns an tuple.
9380
9381    Examples:
9382        >>> tuple_(1, 'x').sql()
9383        '(1, x)'
9384
9385    Args:
9386        expressions: the expressions to add to the tuple.
9387        copy: whether to copy the argument expressions.
9388        dialect: the source dialect.
9389        kwargs: the kwargs used to instantiate the function of interest.
9390
9391    Returns:
9392        A tuple expression.
9393    """
9394    return Tuple(
9395        expressions=[
9396            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9397            for expression in expressions
9398        ]
9399    )

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:
9402def true() -> Boolean:
9403    """
9404    Returns a true Boolean expression.
9405    """
9406    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
9409def false() -> Boolean:
9410    """
9411    Returns a false Boolean expression.
9412    """
9413    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
9416def null() -> Null:
9417    """
9418    Returns a Null expression.
9419    """
9420    return Null()

Returns a Null expression.

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