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

Retrieves the argument with key "this".

expression: Any
138    @property
139    def expression(self) -> t.Any:
140        """
141        Retrieves the argument with key "expression".
142        """
143        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
145    @property
146    def expressions(self) -> t.List[t.Any]:
147        """
148        Retrieves the argument with key "expressions".
149        """
150        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

is_number: bool
173    @property
174    def is_number(self) -> bool:
175        """
176        Checks whether a Literal expression is a number.
177        """
178        return isinstance(self, Literal) and not self.args["is_string"]

Checks whether a Literal expression is a number.

is_negative: bool
180    @property
181    def is_negative(self) -> bool:
182        """
183        Checks whether an expression is negative.
184
185        Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.
186        """
187        return isinstance(self, Neg) or (self.is_number and self.this.startswith("-"))

Checks whether an expression is negative.

Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.

is_int: bool
189    @property
190    def is_int(self) -> bool:
191        """
192        Checks whether a Literal expression is an integer.
193        """
194        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
196    @property
197    def is_star(self) -> bool:
198        """Checks whether an expression is a star."""
199        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
210    @property
211    def alias_column_names(self) -> t.List[str]:
212        table_alias = self.args.get("alias")
213        if not table_alias:
214            return []
215        return [c.name for c in table_alias.args.get("columns") or []]
name: str
217    @property
218    def name(self) -> str:
219        return self.text("this")
alias_or_name: str
221    @property
222    def alias_or_name(self) -> str:
223        return self.alias or self.name
output_name: str
225    @property
226    def output_name(self) -> str:
227        """
228        Name of the output column if this expression is a selection.
229
230        If the Expression has no output name, an empty string is returned.
231
232        Example:
233            >>> from sqlglot import parse_one
234            >>> parse_one("SELECT a").expressions[0].output_name
235            'a'
236            >>> parse_one("SELECT b AS c").expressions[0].output_name
237            'c'
238            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
239            ''
240        """
241        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]
243    @property
244    def type(self) -> t.Optional[DataType]:
245        return self._type
def is_type(self, *dtypes) -> bool:
253    def is_type(self, *dtypes) -> bool:
254        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
256    def is_leaf(self) -> bool:
257        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
259    @property
260    def meta(self) -> t.Dict[str, t.Any]:
261        if self._meta is None:
262            self._meta = {}
263        return self._meta
def copy(self):
299    def copy(self):
300        """
301        Returns a deep copy of the expression.
302        """
303        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]] = None) -> None:
305    def add_comments(self, comments: t.Optional[t.List[str]] = None) -> None:
306        if self.comments is None:
307            self.comments = []
308
309        if comments:
310            for comment in comments:
311                _, *meta = comment.split(SQLGLOT_META)
312                if meta:
313                    for kv in "".join(meta).split(","):
314                        k, *v = kv.split("=")
315                        value = v[0].strip() if v else True
316                        self.meta[k.strip()] = value
317                self.comments.append(comment)
def pop_comments(self) -> List[str]:
319    def pop_comments(self) -> t.List[str]:
320        comments = self.comments or []
321        self.comments = None
322        return comments
def append(self, arg_key: str, value: Any) -> None:
324    def append(self, arg_key: str, value: t.Any) -> None:
325        """
326        Appends value to arg_key if it's a list or sets it as a new list.
327
328        Args:
329            arg_key (str): name of the list expression arg
330            value (Any): value to append to the list
331        """
332        if type(self.args.get(arg_key)) is not list:
333            self.args[arg_key] = []
334        self._set_parent(arg_key, value)
335        values = self.args[arg_key]
336        if hasattr(value, "parent"):
337            value.index = len(values)
338        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) -> None:
340    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
341        """
342        Sets arg_key to value.
343
344        Args:
345            arg_key: name of the expression arg.
346            value: value to set the arg to.
347            index: if the arg is a list, this specifies what position to add the value in it.
348        """
349        if index is not None:
350            expressions = self.args.get(arg_key) or []
351
352            if seq_get(expressions, index) is None:
353                return
354            if value is None:
355                expressions.pop(index)
356                for v in expressions[index:]:
357                    v.index = v.index - 1
358                return
359
360            if isinstance(value, list):
361                expressions.pop(index)
362                expressions[index:index] = value
363            else:
364                expressions[index] = value
365
366            value = expressions
367        elif value is None:
368            self.args.pop(arg_key, None)
369            return
370
371        self.args[arg_key] = value
372        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.
depth: int
386    @property
387    def depth(self) -> int:
388        """
389        Returns the depth of this tree.
390        """
391        if self.parent:
392            return self.parent.depth + 1
393        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
395    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
396        """Yields the key and expression for all arguments, exploding list args."""
397        # remove tuple when python 3.7 is deprecated
398        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
399            if type(vs) is list:
400                for v in reversed(vs) if reverse else vs:
401                    if hasattr(v, "parent"):
402                        yield v
403            else:
404                if hasattr(vs, "parent"):
405                    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]:
407    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
408        """
409        Returns the first node in this tree which matches at least one of
410        the specified types.
411
412        Args:
413            expression_types: the expression type(s) to match.
414            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
415
416        Returns:
417            The node which matches the criteria or None if no such node was found.
418        """
419        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]:
421    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
422        """
423        Returns a generator object which visits all nodes in this tree and only
424        yields those that match at least one of the specified expression types.
425
426        Args:
427            expression_types: the expression type(s) to match.
428            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
429
430        Returns:
431            The generator object.
432        """
433        for expression in self.walk(bfs=bfs):
434            if isinstance(expression, expression_types):
435                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]:
437    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
438        """
439        Returns a nearest parent matching expression_types.
440
441        Args:
442            expression_types: the expression type(s) to match.
443
444        Returns:
445            The parent node.
446        """
447        ancestor = self.parent
448        while ancestor and not isinstance(ancestor, expression_types):
449            ancestor = ancestor.parent
450        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]
452    @property
453    def parent_select(self) -> t.Optional[Select]:
454        """
455        Returns the parent select statement.
456        """
457        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
459    @property
460    def same_parent(self) -> bool:
461        """Returns if the parent is the same class as itself."""
462        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
464    def root(self) -> Expression:
465        """
466        Returns the root expression of this tree.
467        """
468        expression = self
469        while expression.parent:
470            expression = expression.parent
471        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
473    def walk(
474        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
475    ) -> t.Iterator[Expression]:
476        """
477        Returns a generator object which visits all nodes in this tree.
478
479        Args:
480            bfs: if set to True the BFS traversal order will be applied,
481                otherwise the DFS traversal will be used instead.
482            prune: callable that returns True if the generator should stop traversing
483                this branch of the tree.
484
485        Returns:
486            the generator object.
487        """
488        if bfs:
489            yield from self.bfs(prune=prune)
490        else:
491            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]:
493    def dfs(
494        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
495    ) -> t.Iterator[Expression]:
496        """
497        Returns a generator object which visits all nodes in this tree in
498        the DFS (Depth-first) order.
499
500        Returns:
501            The generator object.
502        """
503        stack = [self]
504
505        while stack:
506            node = stack.pop()
507
508            yield node
509
510            if prune and prune(node):
511                continue
512
513            for v in node.iter_expressions(reverse=True):
514                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]:
516    def bfs(
517        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
518    ) -> t.Iterator[Expression]:
519        """
520        Returns a generator object which visits all nodes in this tree in
521        the BFS (Breadth-first) order.
522
523        Returns:
524            The generator object.
525        """
526        queue = deque([self])
527
528        while queue:
529            node = queue.popleft()
530
531            yield node
532
533            if prune and prune(node):
534                continue
535
536            for v in node.iter_expressions():
537                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):
539    def unnest(self):
540        """
541        Returns the first non parenthesis child or self.
542        """
543        expression = self
544        while type(expression) is Paren:
545            expression = expression.this
546        return expression

Returns the first non parenthesis child or self.

def unalias(self):
548    def unalias(self):
549        """
550        Returns the inner expression if this is an Alias.
551        """
552        if isinstance(self, Alias):
553            return self.this
554        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
556    def unnest_operands(self):
557        """
558        Returns unnested operands as a tuple.
559        """
560        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
747    @classmethod
748    def load(cls, obj):
749        """
750        Load a dict (as returned by `Expression.dump`) into an Expression instance.
751        """
752        from sqlglot.serde import load
753
754        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
756    def and_(
757        self,
758        *expressions: t.Optional[ExpOrStr],
759        dialect: DialectType = None,
760        copy: bool = True,
761        **opts,
762    ) -> Condition:
763        """
764        AND this condition with one or multiple expressions.
765
766        Example:
767            >>> condition("x=1").and_("y=1").sql()
768            'x = 1 AND y = 1'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expression` instance is passed, it will be used as-is.
773            dialect: the dialect used to parse the input expression.
774            copy: whether to copy the involved expressions (only applies to Expressions).
775            opts: other options to use to parse the input expressions.
776
777        Returns:
778            The new And condition.
779        """
780        return and_(self, *expressions, dialect=dialect, copy=copy, **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).
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
782    def or_(
783        self,
784        *expressions: t.Optional[ExpOrStr],
785        dialect: DialectType = None,
786        copy: bool = True,
787        **opts,
788    ) -> Condition:
789        """
790        OR this condition with one or multiple expressions.
791
792        Example:
793            >>> condition("x=1").or_("y=1").sql()
794            'x = 1 OR 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            opts: other options to use to parse the input expressions.
802
803        Returns:
804            The new Or condition.
805        """
806        return or_(self, *expressions, dialect=dialect, copy=copy, **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).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
808    def not_(self, copy: bool = True):
809        """
810        Wrap this condition with NOT.
811
812        Example:
813            >>> condition("x=1").not_().sql()
814            'NOT x = 1'
815
816        Args:
817            copy: whether to copy this object.
818
819        Returns:
820            The new Not instance.
821        """
822        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether to copy this object.
Returns:

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
824    def as_(
825        self,
826        alias: str | Identifier,
827        quoted: t.Optional[bool] = None,
828        dialect: DialectType = None,
829        copy: bool = True,
830        **opts,
831    ) -> Alias:
832        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:
857    def isin(
858        self,
859        *expressions: t.Any,
860        query: t.Optional[ExpOrStr] = None,
861        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
862        copy: bool = True,
863        **opts,
864    ) -> In:
865        subquery = maybe_parse(query, copy=copy, **opts) if query else None
866        if subquery and not isinstance(subquery, Subquery):
867            subquery = subquery.subquery(copy=False)
868
869        return In(
870            this=maybe_copy(self, copy),
871            expressions=[convert(e, copy=copy) for e in expressions],
872            query=subquery,
873            unnest=(
874                Unnest(
875                    expressions=[
876                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
877                        for e in ensure_list(unnest)
878                    ]
879                )
880                if unnest
881                else None
882            ),
883        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
885    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
886        return Between(
887            this=maybe_copy(self, copy),
888            low=convert(low, copy=copy, **opts),
889            high=convert(high, copy=copy, **opts),
890        )
def is_( self, other: Union[str, Expression]) -> Is:
892    def is_(self, other: ExpOrStr) -> Is:
893        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
895    def like(self, other: ExpOrStr) -> Like:
896        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
898    def ilike(self, other: ExpOrStr) -> ILike:
899        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
901    def eq(self, other: t.Any) -> EQ:
902        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
904    def neq(self, other: t.Any) -> NEQ:
905        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
907    def rlike(self, other: ExpOrStr) -> RegexpLike:
908        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
910    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
911        div = self._binop(Div, other)
912        div.args["typed"] = typed
913        div.args["safe"] = safe
914        return div
def asc(self, nulls_first: bool = True) -> Ordered:
916    def asc(self, nulls_first: bool = True) -> Ordered:
917        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
919    def desc(self, nulls_first: bool = False) -> Ordered:
920        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):
1003class Condition(Expression):
1004    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1075    def offset(
1076        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1077    ) -> Q:
1078        """
1079        Set the OFFSET expression.
1080
1081        Example:
1082            >>> Select().from_("tbl").select("x").offset(10).sql()
1083            'SELECT x FROM tbl OFFSET 10'
1084
1085        Args:
1086            expression: the SQL code string to parse.
1087                This can also be an integer.
1088                If a `Offset` instance is passed, this is used as-is.
1089                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1090            dialect: the dialect used to parse the input expression.
1091            copy: if `False`, modify this expression instance in-place.
1092            opts: other options to use to parse the input expressions.
1093
1094        Returns:
1095            The modified Select expression.
1096        """
1097        return _apply_builder(
1098            expression=expression,
1099            instance=self,
1100            arg="offset",
1101            into=Offset,
1102            prefix="OFFSET",
1103            dialect=dialect,
1104            copy=copy,
1105            into_arg="expression",
1106            **opts,
1107        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1109    def order_by(
1110        self: Q,
1111        *expressions: t.Optional[ExpOrStr],
1112        append: bool = True,
1113        dialect: DialectType = None,
1114        copy: bool = True,
1115        **opts,
1116    ) -> Q:
1117        """
1118        Set the ORDER BY expression.
1119
1120        Example:
1121            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1122            'SELECT x FROM tbl ORDER BY x DESC'
1123
1124        Args:
1125            *expressions: the SQL code strings to parse.
1126                If a `Group` instance is passed, this is used as-is.
1127                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1128            append: if `True`, add to any existing expressions.
1129                Otherwise, this flattens all the `Order` expression into a single expression.
1130            dialect: the dialect used to parse the input expression.
1131            copy: if `False`, modify this expression instance in-place.
1132            opts: other options to use to parse the input expressions.
1133
1134        Returns:
1135            The modified Select expression.
1136        """
1137        return _apply_child_list_builder(
1138            *expressions,
1139            instance=self,
1140            arg="order",
1141            append=append,
1142            copy=copy,
1143            prefix="ORDER BY",
1144            into=Order,
1145            dialect=dialect,
1146            **opts,
1147        )

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

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

selects: List[Expression]
1155    @property
1156    def selects(self) -> t.List[Expression]:
1157        """Returns the query's projections."""
1158        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1160    @property
1161    def named_selects(self) -> t.List[str]:
1162        """Returns the output names of the query's projections."""
1163        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1165    def select(
1166        self: Q,
1167        *expressions: t.Optional[ExpOrStr],
1168        append: bool = True,
1169        dialect: DialectType = None,
1170        copy: bool = True,
1171        **opts,
1172    ) -> Q:
1173        """
1174        Append to or set the SELECT expressions.
1175
1176        Example:
1177            >>> Select().select("x", "y").sql()
1178            'SELECT x, y'
1179
1180        Args:
1181            *expressions: the SQL code strings to parse.
1182                If an `Expression` instance is passed, it will be used as-is.
1183            append: if `True`, add to any existing expressions.
1184                Otherwise, this resets the expressions.
1185            dialect: the dialect used to parse the input expressions.
1186            copy: if `False`, modify this expression instance in-place.
1187            opts: other options to use to parse the input expressions.
1188
1189        Returns:
1190            The modified Query expression.
1191        """
1192        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1194    def with_(
1195        self: Q,
1196        alias: ExpOrStr,
1197        as_: ExpOrStr,
1198        recursive: t.Optional[bool] = None,
1199        append: bool = True,
1200        dialect: DialectType = None,
1201        copy: bool = True,
1202        **opts,
1203    ) -> Q:
1204        """
1205        Append to or set the common table expressions.
1206
1207        Example:
1208            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1209            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1210
1211        Args:
1212            alias: the SQL code string to parse as the table name.
1213                If an `Expression` instance is passed, this is used as-is.
1214            as_: the SQL code string to parse as the table expression.
1215                If an `Expression` instance is passed, it will be used as-is.
1216            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1217            append: if `True`, add to any existing expressions.
1218                Otherwise, this resets the expressions.
1219            dialect: the dialect used to parse the input expression.
1220            copy: if `False`, modify this expression instance in-place.
1221            opts: other options to use to parse the input expressions.
1222
1223        Returns:
1224            The modified expression.
1225        """
1226        return _apply_cte_builder(
1227            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1228        )

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.
  • 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.

def union( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1230    def union(
1231        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1232    ) -> Union:
1233        """
1234        Builds a UNION expression.
1235
1236        Example:
1237            >>> import sqlglot
1238            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1239            'SELECT * FROM foo UNION SELECT * FROM bla'
1240
1241        Args:
1242            expression: the SQL code string.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            distinct: set the DISTINCT flag if and only if this is true.
1245            dialect: the dialect used to parse the input expression.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The new Union expression.
1250        """
1251        return union(left=self, right=expression, 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:
  • expression: the SQL code string. If an Expression instance is passed, it 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, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1253    def intersect(
1254        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1255    ) -> Intersect:
1256        """
1257        Builds an INTERSECT expression.
1258
1259        Example:
1260            >>> import sqlglot
1261            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1262            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1263
1264        Args:
1265            expression: the SQL code string.
1266                If an `Expression` instance is passed, it will be used as-is.
1267            distinct: set the DISTINCT flag if and only if this is true.
1268            dialect: the dialect used to parse the input expression.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The new Intersect expression.
1273        """
1274        return intersect(left=self, right=expression, 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:
  • expression: the SQL code string. If an Expression instance is passed, it 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, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1276    def except_(
1277        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1278    ) -> Except:
1279        """
1280        Builds an EXCEPT expression.
1281
1282        Example:
1283            >>> import sqlglot
1284            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1285            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1286
1287        Args:
1288            expression: the SQL code string.
1289                If an `Expression` instance is passed, it will be used as-is.
1290            distinct: set the DISTINCT flag if and only if this is true.
1291            dialect: the dialect used to parse the input expression.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The new Except expression.
1296        """
1297        return except_(left=self, right=expression, 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:
  • expression: the SQL code string. If an Expression instance is passed, it 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):
1300class UDTF(DerivedTable):
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
selects: List[Expression]
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1307class Cache(Expression):
1308    arg_types = {
1309        "this": True,
1310        "lazy": False,
1311        "options": False,
1312        "expression": False,
1313    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1316class Uncache(Expression):
1317    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1320class Refresh(Expression):
1321    pass
key = 'refresh'
class DDL(Expression):
1324class DDL(Expression):
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []
1330
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        return self.expression.selects if isinstance(self.expression, Query) else []
1335
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []

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

selects: List[Expression]
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        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]
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []

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

key = 'ddl'
class DML(Expression):
1345class DML(Expression):
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> DML:
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )

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):
1382class Create(DDL):
1383    arg_types = {
1384        "with": False,
1385        "this": True,
1386        "kind": True,
1387        "expression": False,
1388        "exists": False,
1389        "properties": False,
1390        "replace": False,
1391        "unique": False,
1392        "indexes": False,
1393        "no_schema_binding": False,
1394        "begin": False,
1395        "end": False,
1396        "clone": False,
1397    }
1398
1399    @property
1400    def kind(self) -> t.Optional[str]:
1401        kind = self.args.get("kind")
1402        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False}
kind: Optional[str]
1399    @property
1400    def kind(self) -> t.Optional[str]:
1401        kind = self.args.get("kind")
1402        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1405class SequenceProperties(Expression):
1406    arg_types = {
1407        "increment": False,
1408        "minvalue": False,
1409        "maxvalue": False,
1410        "cache": False,
1411        "start": False,
1412        "owned": False,
1413        "options": False,
1414    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1417class TruncateTable(Expression):
1418    arg_types = {
1419        "expressions": True,
1420        "is_database": False,
1421        "exists": False,
1422        "only": False,
1423        "cluster": False,
1424        "identity": False,
1425        "option": False,
1426        "partition": False,
1427    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1433class Clone(Expression):
1434    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1437class Describe(Expression):
1438    arg_types = {"this": True, "style": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1441class Kill(Expression):
1442    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1445class Pragma(Expression):
1446    pass
key = 'pragma'
class Declare(Expression):
1449class Declare(Expression):
1450    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1453class DeclareItem(Expression):
1454    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1457class Set(Expression):
1458    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1461class Heredoc(Expression):
1462    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1465class SetItem(Expression):
1466    arg_types = {
1467        "this": False,
1468        "expressions": False,
1469        "kind": False,
1470        "collate": False,  # MySQL SET NAMES statement
1471        "global": False,
1472    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1475class Show(Expression):
1476    arg_types = {
1477        "this": True,
1478        "history": False,
1479        "terse": False,
1480        "target": False,
1481        "offset": False,
1482        "starts_with": False,
1483        "limit": False,
1484        "from": False,
1485        "like": False,
1486        "where": False,
1487        "db": False,
1488        "scope": False,
1489        "scope_kind": False,
1490        "full": False,
1491        "mutex": False,
1492        "query": False,
1493        "channel": False,
1494        "global": False,
1495        "log": False,
1496        "position": False,
1497        "types": False,
1498    }
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}
key = 'show'
class UserDefinedFunction(Expression):
1501class UserDefinedFunction(Expression):
1502    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1505class CharacterSet(Expression):
1506    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1509class With(Expression):
1510    arg_types = {"expressions": True, "recursive": False}
1511
1512    @property
1513    def recursive(self) -> bool:
1514        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1512    @property
1513    def recursive(self) -> bool:
1514        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1517class WithinGroup(Expression):
1518    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1523class CTE(DerivedTable):
1524    arg_types = {
1525        "this": True,
1526        "alias": True,
1527        "scalar": False,
1528        "materialized": False,
1529    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1532class ProjectionDef(Expression):
1533    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1536class TableAlias(Expression):
1537    arg_types = {"this": False, "columns": False}
1538
1539    @property
1540    def columns(self):
1541        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1539    @property
1540    def columns(self):
1541        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1544class BitString(Condition):
1545    pass
key = 'bitstring'
class HexString(Condition):
1548class HexString(Condition):
1549    pass
key = 'hexstring'
class ByteString(Condition):
1552class ByteString(Condition):
1553    pass
key = 'bytestring'
class RawString(Condition):
1556class RawString(Condition):
1557    pass
key = 'rawstring'
class UnicodeString(Condition):
1560class UnicodeString(Condition):
1561    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1564class Column(Condition):
1565    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1566
1567    @property
1568    def table(self) -> str:
1569        return self.text("table")
1570
1571    @property
1572    def db(self) -> str:
1573        return self.text("db")
1574
1575    @property
1576    def catalog(self) -> str:
1577        return self.text("catalog")
1578
1579    @property
1580    def output_name(self) -> str:
1581        return self.name
1582
1583    @property
1584    def parts(self) -> t.List[Identifier]:
1585        """Return the parts of a column in order catalog, db, table, name."""
1586        return [
1587            t.cast(Identifier, self.args[part])
1588            for part in ("catalog", "db", "table", "this")
1589            if self.args.get(part)
1590        ]
1591
1592    def to_dot(self) -> Dot | Identifier:
1593        """Converts the column into a dot expression."""
1594        parts = self.parts
1595        parent = self.parent
1596
1597        while parent:
1598            if isinstance(parent, Dot):
1599                parts.append(parent.expression)
1600            parent = parent.parent
1601
1602        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
1567    @property
1568    def table(self) -> str:
1569        return self.text("table")
db: str
1571    @property
1572    def db(self) -> str:
1573        return self.text("db")
catalog: str
1575    @property
1576    def catalog(self) -> str:
1577        return self.text("catalog")
output_name: str
1579    @property
1580    def output_name(self) -> str:
1581        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]
1583    @property
1584    def parts(self) -> t.List[Identifier]:
1585        """Return the parts of a column in order catalog, db, table, name."""
1586        return [
1587            t.cast(Identifier, self.args[part])
1588            for part in ("catalog", "db", "table", "this")
1589            if self.args.get(part)
1590        ]

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

def to_dot(self) -> Dot | Identifier:
1592    def to_dot(self) -> Dot | Identifier:
1593        """Converts the column into a dot expression."""
1594        parts = self.parts
1595        parent = self.parent
1596
1597        while parent:
1598            if isinstance(parent, Dot):
1599                parts.append(parent.expression)
1600            parent = parent.parent
1601
1602        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1605class ColumnPosition(Expression):
1606    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1609class ColumnDef(Expression):
1610    arg_types = {
1611        "this": True,
1612        "kind": False,
1613        "constraints": False,
1614        "exists": False,
1615        "position": False,
1616    }
1617
1618    @property
1619    def constraints(self) -> t.List[ColumnConstraint]:
1620        return self.args.get("constraints") or []
1621
1622    @property
1623    def kind(self) -> t.Optional[DataType]:
1624        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1618    @property
1619    def constraints(self) -> t.List[ColumnConstraint]:
1620        return self.args.get("constraints") or []
kind: Optional[DataType]
1622    @property
1623    def kind(self) -> t.Optional[DataType]:
1624        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1627class AlterColumn(Expression):
1628    arg_types = {
1629        "this": True,
1630        "dtype": False,
1631        "collate": False,
1632        "using": False,
1633        "default": False,
1634        "drop": False,
1635        "comment": False,
1636    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1640class AlterDistStyle(Expression):
1641    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1644class AlterSortKey(Expression):
1645    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1648class AlterSet(Expression):
1649    arg_types = {
1650        "expressions": False,
1651        "option": False,
1652        "tablespace": False,
1653        "access_method": False,
1654        "file_format": False,
1655        "copy_options": False,
1656        "tag": False,
1657        "location": False,
1658        "serde": False,
1659    }
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):
1662class RenameColumn(Expression):
1663    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1666class RenameTable(Expression):
1667    pass
key = 'renametable'
class SwapTable(Expression):
1670class SwapTable(Expression):
1671    pass
key = 'swaptable'
class Comment(Expression):
1674class Comment(Expression):
1675    arg_types = {
1676        "this": True,
1677        "kind": True,
1678        "expression": True,
1679        "exists": False,
1680        "materialized": False,
1681    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1684class Comprehension(Expression):
1685    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):
1689class MergeTreeTTLAction(Expression):
1690    arg_types = {
1691        "this": True,
1692        "delete": False,
1693        "recompress": False,
1694        "to_disk": False,
1695        "to_volume": False,
1696    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1700class MergeTreeTTL(Expression):
1701    arg_types = {
1702        "expressions": True,
1703        "where": False,
1704        "group": False,
1705        "aggregates": False,
1706    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1710class IndexConstraintOption(Expression):
1711    arg_types = {
1712        "key_block_size": False,
1713        "using": False,
1714        "parser": False,
1715        "comment": False,
1716        "visible": False,
1717        "engine_attr": False,
1718        "secondary_engine_attr": False,
1719    }
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):
1722class ColumnConstraint(Expression):
1723    arg_types = {"this": False, "kind": True}
1724
1725    @property
1726    def kind(self) -> ColumnConstraintKind:
1727        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1725    @property
1726    def kind(self) -> ColumnConstraintKind:
1727        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1730class ColumnConstraintKind(Expression):
1731    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1734class AutoIncrementColumnConstraint(ColumnConstraintKind):
1735    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1738class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1739    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1742class CaseSpecificColumnConstraint(ColumnConstraintKind):
1743    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1746class CharacterSetColumnConstraint(ColumnConstraintKind):
1747    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1750class CheckColumnConstraint(ColumnConstraintKind):
1751    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1754class ClusteredColumnConstraint(ColumnConstraintKind):
1755    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1758class CollateColumnConstraint(ColumnConstraintKind):
1759    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1762class CommentColumnConstraint(ColumnConstraintKind):
1763    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1766class CompressColumnConstraint(ColumnConstraintKind):
1767    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1770class DateFormatColumnConstraint(ColumnConstraintKind):
1771    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1774class DefaultColumnConstraint(ColumnConstraintKind):
1775    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1778class EncodeColumnConstraint(ColumnConstraintKind):
1779    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1783class ExcludeColumnConstraint(ColumnConstraintKind):
1784    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1787class EphemeralColumnConstraint(ColumnConstraintKind):
1788    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1791class WithOperator(Expression):
1792    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1795class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1796    # this: True -> ALWAYS, this: False -> BY DEFAULT
1797    arg_types = {
1798        "this": False,
1799        "expression": False,
1800        "on_null": False,
1801        "start": False,
1802        "increment": False,
1803        "minvalue": False,
1804        "maxvalue": False,
1805        "cycle": False,
1806    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1809class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1810    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1815class IndexColumnConstraint(ColumnConstraintKind):
1816    arg_types = {
1817        "this": False,
1818        "expressions": False,
1819        "kind": False,
1820        "index_type": False,
1821        "options": False,
1822        "expression": False,  # Clickhouse
1823        "granularity": False,
1824    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1827class InlineLengthColumnConstraint(ColumnConstraintKind):
1828    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1831class NonClusteredColumnConstraint(ColumnConstraintKind):
1832    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1835class NotForReplicationColumnConstraint(ColumnConstraintKind):
1836    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1839class NotNullColumnConstraint(ColumnConstraintKind):
1840    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1844class OnUpdateColumnConstraint(ColumnConstraintKind):
1845    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1849class TransformColumnConstraint(ColumnConstraintKind):
1850    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1853class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1854    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1857class TitleColumnConstraint(ColumnConstraintKind):
1858    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1861class UniqueColumnConstraint(ColumnConstraintKind):
1862    arg_types = {"this": False, "index_type": False, "on_conflict": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1865class UppercaseColumnConstraint(ColumnConstraintKind):
1866    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1869class PathColumnConstraint(ColumnConstraintKind):
1870    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1875class ComputedColumnConstraint(ColumnConstraintKind):
1876    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1879class Constraint(Expression):
1880    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1883class Delete(DML):
1884    arg_types = {
1885        "with": False,
1886        "this": False,
1887        "using": False,
1888        "where": False,
1889        "returning": False,
1890        "limit": False,
1891        "tables": False,  # Multiple-Table Syntax (MySQL)
1892    }
1893
1894    def delete(
1895        self,
1896        table: ExpOrStr,
1897        dialect: DialectType = None,
1898        copy: bool = True,
1899        **opts,
1900    ) -> Delete:
1901        """
1902        Create a DELETE expression or replace the table on an existing DELETE expression.
1903
1904        Example:
1905            >>> delete("tbl").sql()
1906            'DELETE FROM tbl'
1907
1908        Args:
1909            table: the table from which to delete.
1910            dialect: the dialect used to parse the input expression.
1911            copy: if `False`, modify this expression instance in-place.
1912            opts: other options to use to parse the input expressions.
1913
1914        Returns:
1915            Delete: the modified expression.
1916        """
1917        return _apply_builder(
1918            expression=table,
1919            instance=self,
1920            arg="this",
1921            dialect=dialect,
1922            into=Table,
1923            copy=copy,
1924            **opts,
1925        )
1926
1927    def where(
1928        self,
1929        *expressions: t.Optional[ExpOrStr],
1930        append: bool = True,
1931        dialect: DialectType = None,
1932        copy: bool = True,
1933        **opts,
1934    ) -> Delete:
1935        """
1936        Append to or set the WHERE expressions.
1937
1938        Example:
1939            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1940            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1941
1942        Args:
1943            *expressions: the SQL code strings to parse.
1944                If an `Expression` instance is passed, it will be used as-is.
1945                Multiple expressions are combined with an AND operator.
1946            append: if `True`, AND the new expressions to any existing expression.
1947                Otherwise, this resets the expression.
1948            dialect: the dialect used to parse the input expressions.
1949            copy: if `False`, modify this expression instance in-place.
1950            opts: other options to use to parse the input expressions.
1951
1952        Returns:
1953            Delete: the modified expression.
1954        """
1955        return _apply_conjunction_builder(
1956            *expressions,
1957            instance=self,
1958            arg="where",
1959            append=append,
1960            into=Where,
1961            dialect=dialect,
1962            copy=copy,
1963            **opts,
1964        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1894    def delete(
1895        self,
1896        table: ExpOrStr,
1897        dialect: DialectType = None,
1898        copy: bool = True,
1899        **opts,
1900    ) -> Delete:
1901        """
1902        Create a DELETE expression or replace the table on an existing DELETE expression.
1903
1904        Example:
1905            >>> delete("tbl").sql()
1906            'DELETE FROM tbl'
1907
1908        Args:
1909            table: the table from which to delete.
1910            dialect: the dialect used to parse the input expression.
1911            copy: if `False`, modify this expression instance in-place.
1912            opts: other options to use to parse the input expressions.
1913
1914        Returns:
1915            Delete: the modified expression.
1916        """
1917        return _apply_builder(
1918            expression=table,
1919            instance=self,
1920            arg="this",
1921            dialect=dialect,
1922            into=Table,
1923            copy=copy,
1924            **opts,
1925        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1927    def where(
1928        self,
1929        *expressions: t.Optional[ExpOrStr],
1930        append: bool = True,
1931        dialect: DialectType = None,
1932        copy: bool = True,
1933        **opts,
1934    ) -> Delete:
1935        """
1936        Append to or set the WHERE expressions.
1937
1938        Example:
1939            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1940            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1941
1942        Args:
1943            *expressions: the SQL code strings to parse.
1944                If an `Expression` instance is passed, it will be used as-is.
1945                Multiple expressions are combined with an AND operator.
1946            append: if `True`, AND the new expressions to any existing expression.
1947                Otherwise, this resets the expression.
1948            dialect: the dialect used to parse the input expressions.
1949            copy: if `False`, modify this expression instance in-place.
1950            opts: other options to use to parse the input expressions.
1951
1952        Returns:
1953            Delete: the modified expression.
1954        """
1955        return _apply_conjunction_builder(
1956            *expressions,
1957            instance=self,
1958            arg="where",
1959            append=append,
1960            into=Where,
1961            dialect=dialect,
1962            copy=copy,
1963            **opts,
1964        )

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):
1967class Drop(Expression):
1968    arg_types = {
1969        "this": False,
1970        "kind": False,
1971        "expressions": False,
1972        "exists": False,
1973        "temporary": False,
1974        "materialized": False,
1975        "cascade": False,
1976        "constraints": False,
1977        "purge": False,
1978        "cluster": False,
1979    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
key = 'drop'
class Filter(Expression):
1982class Filter(Expression):
1983    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1986class Check(Expression):
1987    pass
key = 'check'
class Connect(Expression):
1991class Connect(Expression):
1992    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
1995class CopyParameter(Expression):
1996    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'copyparameter'
class Copy(Expression):
1999class Copy(Expression):
2000    arg_types = {
2001        "this": True,
2002        "kind": True,
2003        "files": True,
2004        "credentials": False,
2005        "format": False,
2006        "params": False,
2007    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2010class Credentials(Expression):
2011    arg_types = {
2012        "credentials": False,
2013        "encryption": False,
2014        "storage": False,
2015        "iam_role": False,
2016        "region": False,
2017    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2020class Prior(Expression):
2021    pass
key = 'prior'
class Directory(Expression):
2024class Directory(Expression):
2025    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2026    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2029class ForeignKey(Expression):
2030    arg_types = {
2031        "expressions": True,
2032        "reference": False,
2033        "delete": False,
2034        "update": False,
2035    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2038class ColumnPrefix(Expression):
2039    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2042class PrimaryKey(Expression):
2043    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2048class Into(Expression):
2049    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2052class From(Expression):
2053    @property
2054    def name(self) -> str:
2055        return self.this.name
2056
2057    @property
2058    def alias_or_name(self) -> str:
2059        return self.this.alias_or_name
name: str
2053    @property
2054    def name(self) -> str:
2055        return self.this.name
alias_or_name: str
2057    @property
2058    def alias_or_name(self) -> str:
2059        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2062class Having(Expression):
2063    pass
key = 'having'
class Hint(Expression):
2066class Hint(Expression):
2067    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2070class JoinHint(Expression):
2071    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2074class Identifier(Expression):
2075    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2076
2077    @property
2078    def quoted(self) -> bool:
2079        return bool(self.args.get("quoted"))
2080
2081    @property
2082    def hashable_args(self) -> t.Any:
2083        return (self.this, self.quoted)
2084
2085    @property
2086    def output_name(self) -> str:
2087        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2077    @property
2078    def quoted(self) -> bool:
2079        return bool(self.args.get("quoted"))
hashable_args: Any
2081    @property
2082    def hashable_args(self) -> t.Any:
2083        return (self.this, self.quoted)
output_name: str
2085    @property
2086    def output_name(self) -> str:
2087        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):
2091class Opclass(Expression):
2092    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2095class Index(Expression):
2096    arg_types = {
2097        "this": False,
2098        "table": False,
2099        "unique": False,
2100        "primary": False,
2101        "amp": False,  # teradata
2102        "params": False,
2103    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2106class IndexParameters(Expression):
2107    arg_types = {
2108        "using": False,
2109        "include": False,
2110        "columns": False,
2111        "with_storage": False,
2112        "partition_by": False,
2113        "tablespace": False,
2114        "where": False,
2115    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
2118class Insert(DDL, DML):
2119    arg_types = {
2120        "hint": False,
2121        "with": False,
2122        "is_function": False,
2123        "this": False,
2124        "expression": False,
2125        "conflict": False,
2126        "returning": False,
2127        "overwrite": False,
2128        "exists": False,
2129        "alternative": False,
2130        "where": False,
2131        "ignore": False,
2132        "by_name": False,
2133        "stored": False,
2134    }
2135
2136    def with_(
2137        self,
2138        alias: ExpOrStr,
2139        as_: ExpOrStr,
2140        recursive: t.Optional[bool] = None,
2141        append: bool = True,
2142        dialect: DialectType = None,
2143        copy: bool = True,
2144        **opts,
2145    ) -> Insert:
2146        """
2147        Append to or set the common table expressions.
2148
2149        Example:
2150            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2151            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2152
2153        Args:
2154            alias: the SQL code string to parse as the table name.
2155                If an `Expression` instance is passed, this is used as-is.
2156            as_: the SQL code string to parse as the table expression.
2157                If an `Expression` instance is passed, it will be used as-is.
2158            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2159            append: if `True`, add to any existing expressions.
2160                Otherwise, this resets the expressions.
2161            dialect: the dialect used to parse the input expression.
2162            copy: if `False`, modify this expression instance in-place.
2163            opts: other options to use to parse the input expressions.
2164
2165        Returns:
2166            The modified expression.
2167        """
2168        return _apply_cte_builder(
2169            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2170        )
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}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2136    def with_(
2137        self,
2138        alias: ExpOrStr,
2139        as_: ExpOrStr,
2140        recursive: t.Optional[bool] = None,
2141        append: bool = True,
2142        dialect: DialectType = None,
2143        copy: bool = True,
2144        **opts,
2145    ) -> Insert:
2146        """
2147        Append to or set the common table expressions.
2148
2149        Example:
2150            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2151            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2152
2153        Args:
2154            alias: the SQL code string to parse as the table name.
2155                If an `Expression` instance is passed, this is used as-is.
2156            as_: the SQL code string to parse as the table expression.
2157                If an `Expression` instance is passed, it will be used as-is.
2158            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2159            append: if `True`, add to any existing expressions.
2160                Otherwise, this resets the expressions.
2161            dialect: the dialect used to parse the input expression.
2162            copy: if `False`, modify this expression instance in-place.
2163            opts: other options to use to parse the input expressions.
2164
2165        Returns:
2166            The modified expression.
2167        """
2168        return _apply_cte_builder(
2169            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2170        )

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.
  • 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 OnConflict(Expression):
2173class OnConflict(Expression):
2174    arg_types = {
2175        "duplicate": False,
2176        "expressions": False,
2177        "action": False,
2178        "conflict_keys": False,
2179        "constraint": False,
2180    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2183class Returning(Expression):
2184    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2188class Introducer(Expression):
2189    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2193class National(Expression):
2194    pass
key = 'national'
class LoadData(Expression):
2197class LoadData(Expression):
2198    arg_types = {
2199        "this": True,
2200        "local": False,
2201        "overwrite": False,
2202        "inpath": True,
2203        "partition": False,
2204        "input_format": False,
2205        "serde": False,
2206    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2209class Partition(Expression):
2210    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2213class PartitionRange(Expression):
2214    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2218class PartitionId(Expression):
2219    pass
key = 'partitionid'
class Fetch(Expression):
2222class Fetch(Expression):
2223    arg_types = {
2224        "direction": False,
2225        "count": False,
2226        "percent": False,
2227        "with_ties": False,
2228    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2231class Group(Expression):
2232    arg_types = {
2233        "expressions": False,
2234        "grouping_sets": False,
2235        "cube": False,
2236        "rollup": False,
2237        "totals": False,
2238        "all": False,
2239    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2242class Lambda(Expression):
2243    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2246class Limit(Expression):
2247    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2250class Literal(Condition):
2251    arg_types = {"this": True, "is_string": True}
2252
2253    @property
2254    def hashable_args(self) -> t.Any:
2255        return (self.this, self.args.get("is_string"))
2256
2257    @classmethod
2258    def number(cls, number) -> Literal:
2259        return cls(this=str(number), is_string=False)
2260
2261    @classmethod
2262    def string(cls, string) -> Literal:
2263        return cls(this=str(string), is_string=True)
2264
2265    @property
2266    def output_name(self) -> str:
2267        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2253    @property
2254    def hashable_args(self) -> t.Any:
2255        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2257    @classmethod
2258    def number(cls, number) -> Literal:
2259        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2261    @classmethod
2262    def string(cls, string) -> Literal:
2263        return cls(this=str(string), is_string=True)
output_name: str
2265    @property
2266    def output_name(self) -> str:
2267        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 = 'literal'
class Join(Expression):
2270class Join(Expression):
2271    arg_types = {
2272        "this": True,
2273        "on": False,
2274        "side": False,
2275        "kind": False,
2276        "using": False,
2277        "method": False,
2278        "global": False,
2279        "hint": False,
2280        "match_condition": False,  # Snowflake
2281    }
2282
2283    @property
2284    def method(self) -> str:
2285        return self.text("method").upper()
2286
2287    @property
2288    def kind(self) -> str:
2289        return self.text("kind").upper()
2290
2291    @property
2292    def side(self) -> str:
2293        return self.text("side").upper()
2294
2295    @property
2296    def hint(self) -> str:
2297        return self.text("hint").upper()
2298
2299    @property
2300    def alias_or_name(self) -> str:
2301        return self.this.alias_or_name
2302
2303    def on(
2304        self,
2305        *expressions: t.Optional[ExpOrStr],
2306        append: bool = True,
2307        dialect: DialectType = None,
2308        copy: bool = True,
2309        **opts,
2310    ) -> Join:
2311        """
2312        Append to or set the ON expressions.
2313
2314        Example:
2315            >>> import sqlglot
2316            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2317            'JOIN x ON y = 1'
2318
2319        Args:
2320            *expressions: the SQL code strings to parse.
2321                If an `Expression` instance is passed, it will be used as-is.
2322                Multiple expressions are combined with an AND operator.
2323            append: if `True`, AND the new expressions to any existing expression.
2324                Otherwise, this resets the expression.
2325            dialect: the dialect used to parse the input expressions.
2326            copy: if `False`, modify this expression instance in-place.
2327            opts: other options to use to parse the input expressions.
2328
2329        Returns:
2330            The modified Join expression.
2331        """
2332        join = _apply_conjunction_builder(
2333            *expressions,
2334            instance=self,
2335            arg="on",
2336            append=append,
2337            dialect=dialect,
2338            copy=copy,
2339            **opts,
2340        )
2341
2342        if join.kind == "CROSS":
2343            join.set("kind", None)
2344
2345        return join
2346
2347    def using(
2348        self,
2349        *expressions: t.Optional[ExpOrStr],
2350        append: bool = True,
2351        dialect: DialectType = None,
2352        copy: bool = True,
2353        **opts,
2354    ) -> Join:
2355        """
2356        Append to or set the USING expressions.
2357
2358        Example:
2359            >>> import sqlglot
2360            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2361            'JOIN x USING (foo, bla)'
2362
2363        Args:
2364            *expressions: the SQL code strings to parse.
2365                If an `Expression` instance is passed, it will be used as-is.
2366            append: if `True`, concatenate the new expressions to the existing "using" list.
2367                Otherwise, this resets the expression.
2368            dialect: the dialect used to parse the input expressions.
2369            copy: if `False`, modify this expression instance in-place.
2370            opts: other options to use to parse the input expressions.
2371
2372        Returns:
2373            The modified Join expression.
2374        """
2375        join = _apply_list_builder(
2376            *expressions,
2377            instance=self,
2378            arg="using",
2379            append=append,
2380            dialect=dialect,
2381            copy=copy,
2382            **opts,
2383        )
2384
2385        if join.kind == "CROSS":
2386            join.set("kind", None)
2387
2388        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False}
method: str
2283    @property
2284    def method(self) -> str:
2285        return self.text("method").upper()
kind: str
2287    @property
2288    def kind(self) -> str:
2289        return self.text("kind").upper()
side: str
2291    @property
2292    def side(self) -> str:
2293        return self.text("side").upper()
hint: str
2295    @property
2296    def hint(self) -> str:
2297        return self.text("hint").upper()
alias_or_name: str
2299    @property
2300    def alias_or_name(self) -> str:
2301        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2303    def on(
2304        self,
2305        *expressions: t.Optional[ExpOrStr],
2306        append: bool = True,
2307        dialect: DialectType = None,
2308        copy: bool = True,
2309        **opts,
2310    ) -> Join:
2311        """
2312        Append to or set the ON expressions.
2313
2314        Example:
2315            >>> import sqlglot
2316            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2317            'JOIN x ON y = 1'
2318
2319        Args:
2320            *expressions: the SQL code strings to parse.
2321                If an `Expression` instance is passed, it will be used as-is.
2322                Multiple expressions are combined with an AND operator.
2323            append: if `True`, AND the new expressions to any existing expression.
2324                Otherwise, this resets the expression.
2325            dialect: the dialect used to parse the input expressions.
2326            copy: if `False`, modify this expression instance in-place.
2327            opts: other options to use to parse the input expressions.
2328
2329        Returns:
2330            The modified Join expression.
2331        """
2332        join = _apply_conjunction_builder(
2333            *expressions,
2334            instance=self,
2335            arg="on",
2336            append=append,
2337            dialect=dialect,
2338            copy=copy,
2339            **opts,
2340        )
2341
2342        if join.kind == "CROSS":
2343            join.set("kind", None)
2344
2345        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2347    def using(
2348        self,
2349        *expressions: t.Optional[ExpOrStr],
2350        append: bool = True,
2351        dialect: DialectType = None,
2352        copy: bool = True,
2353        **opts,
2354    ) -> Join:
2355        """
2356        Append to or set the USING expressions.
2357
2358        Example:
2359            >>> import sqlglot
2360            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2361            'JOIN x USING (foo, bla)'
2362
2363        Args:
2364            *expressions: the SQL code strings to parse.
2365                If an `Expression` instance is passed, it will be used as-is.
2366            append: if `True`, concatenate the new expressions to the existing "using" list.
2367                Otherwise, this resets the expression.
2368            dialect: the dialect used to parse the input expressions.
2369            copy: if `False`, modify this expression instance in-place.
2370            opts: other options to use to parse the input expressions.
2371
2372        Returns:
2373            The modified Join expression.
2374        """
2375        join = _apply_list_builder(
2376            *expressions,
2377            instance=self,
2378            arg="using",
2379            append=append,
2380            dialect=dialect,
2381            copy=copy,
2382            **opts,
2383        )
2384
2385        if join.kind == "CROSS":
2386            join.set("kind", None)
2387
2388        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):
2391class Lateral(UDTF):
2392    arg_types = {
2393        "this": True,
2394        "view": False,
2395        "outer": False,
2396        "alias": False,
2397        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2398    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2401class MatchRecognizeMeasure(Expression):
2402    arg_types = {
2403        "this": True,
2404        "window_frame": False,
2405    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2408class MatchRecognize(Expression):
2409    arg_types = {
2410        "partition_by": False,
2411        "order": False,
2412        "measures": False,
2413        "rows": False,
2414        "after": False,
2415        "pattern": False,
2416        "define": False,
2417        "alias": False,
2418    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2423class Final(Expression):
2424    pass
key = 'final'
class Offset(Expression):
2427class Offset(Expression):
2428    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2431class Order(Expression):
2432    arg_types = {
2433        "this": False,
2434        "expressions": True,
2435        "interpolate": False,
2436        "siblings": False,
2437    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2441class WithFill(Expression):
2442    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2447class Cluster(Order):
2448    pass
key = 'cluster'
class Distribute(Order):
2451class Distribute(Order):
2452    pass
key = 'distribute'
class Sort(Order):
2455class Sort(Order):
2456    pass
key = 'sort'
class Ordered(Expression):
2459class Ordered(Expression):
2460    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2463class Property(Expression):
2464    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2467class AllowedValuesProperty(Expression):
2468    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2471class AlgorithmProperty(Property):
2472    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2475class AutoIncrementProperty(Property):
2476    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2480class AutoRefreshProperty(Property):
2481    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2484class BackupProperty(Property):
2485    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2488class BlockCompressionProperty(Property):
2489    arg_types = {
2490        "autotemp": False,
2491        "always": False,
2492        "default": False,
2493        "manual": False,
2494        "never": False,
2495    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2498class CharacterSetProperty(Property):
2499    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2502class ChecksumProperty(Property):
2503    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2506class CollateProperty(Property):
2507    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2510class CopyGrantsProperty(Property):
2511    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2514class DataBlocksizeProperty(Property):
2515    arg_types = {
2516        "size": False,
2517        "units": False,
2518        "minimum": False,
2519        "maximum": False,
2520        "default": False,
2521    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2524class DataDeletionProperty(Property):
2525    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):
2528class DefinerProperty(Property):
2529    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2532class DistKeyProperty(Property):
2533    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2536class DistStyleProperty(Property):
2537    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2540class EngineProperty(Property):
2541    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2544class HeapProperty(Property):
2545    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2548class ToTableProperty(Property):
2549    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2552class ExecuteAsProperty(Property):
2553    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2556class ExternalProperty(Property):
2557    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2560class FallbackProperty(Property):
2561    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2564class FileFormatProperty(Property):
2565    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2568class FreespaceProperty(Property):
2569    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2572class GlobalProperty(Property):
2573    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2576class IcebergProperty(Property):
2577    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2580class InheritsProperty(Property):
2581    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2584class InputModelProperty(Property):
2585    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2588class OutputModelProperty(Property):
2589    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2592class IsolatedLoadingProperty(Property):
2593    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2596class JournalProperty(Property):
2597    arg_types = {
2598        "no": False,
2599        "dual": False,
2600        "before": False,
2601        "local": False,
2602        "after": False,
2603    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2606class LanguageProperty(Property):
2607    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2611class ClusteredByProperty(Property):
2612    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2615class DictProperty(Property):
2616    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2619class DictSubProperty(Property):
2620    pass
key = 'dictsubproperty'
class DictRange(Property):
2623class DictRange(Property):
2624    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2629class OnCluster(Property):
2630    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2633class LikeProperty(Property):
2634    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2637class LocationProperty(Property):
2638    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2641class LockProperty(Property):
2642    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2645class LockingProperty(Property):
2646    arg_types = {
2647        "this": False,
2648        "kind": True,
2649        "for_or_in": False,
2650        "lock_type": True,
2651        "override": False,
2652    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2655class LogProperty(Property):
2656    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2659class MaterializedProperty(Property):
2660    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2663class MergeBlockRatioProperty(Property):
2664    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):
2667class NoPrimaryIndexProperty(Property):
2668    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2671class OnProperty(Property):
2672    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2675class OnCommitProperty(Property):
2676    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2679class PartitionedByProperty(Property):
2680    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2684class PartitionBoundSpec(Expression):
2685    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2686    arg_types = {
2687        "this": False,
2688        "expression": False,
2689        "from_expressions": False,
2690        "to_expressions": False,
2691    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2694class PartitionedOfProperty(Property):
2695    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2696    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2699class RemoteWithConnectionModelProperty(Property):
2700    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2703class ReturnsProperty(Property):
2704    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):
2707class StrictProperty(Property):
2708    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2711class RowFormatProperty(Property):
2712    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2715class RowFormatDelimitedProperty(Property):
2716    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2717    arg_types = {
2718        "fields": False,
2719        "escaped": False,
2720        "collection_items": False,
2721        "map_keys": False,
2722        "lines": False,
2723        "null": False,
2724        "serde": False,
2725    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2728class RowFormatSerdeProperty(Property):
2729    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2733class QueryTransform(Expression):
2734    arg_types = {
2735        "expressions": True,
2736        "command_script": True,
2737        "schema": False,
2738        "row_format_before": False,
2739        "record_writer": False,
2740        "row_format_after": False,
2741        "record_reader": False,
2742    }
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):
2745class SampleProperty(Property):
2746    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2749class SchemaCommentProperty(Property):
2750    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2753class SerdeProperties(Property):
2754    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2757class SetProperty(Property):
2758    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2761class SharingProperty(Property):
2762    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2765class SetConfigProperty(Property):
2766    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2769class SettingsProperty(Property):
2770    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2773class SortKeyProperty(Property):
2774    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2777class SqlReadWriteProperty(Property):
2778    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2781class SqlSecurityProperty(Property):
2782    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2785class StabilityProperty(Property):
2786    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2789class TemporaryProperty(Property):
2790    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2793class TransformModelProperty(Property):
2794    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2797class TransientProperty(Property):
2798    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2801class UnloggedProperty(Property):
2802    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2806class ViewAttributeProperty(Property):
2807    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2810class VolatileProperty(Property):
2811    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2814class WithDataProperty(Property):
2815    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2818class WithJournalTableProperty(Property):
2819    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2822class WithSystemVersioningProperty(Property):
2823    arg_types = {
2824        "on": False,
2825        "this": False,
2826        "data_consistency": False,
2827        "retention_period": False,
2828        "with": True,
2829    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2832class Properties(Expression):
2833    arg_types = {"expressions": True}
2834
2835    NAME_TO_PROPERTY = {
2836        "ALGORITHM": AlgorithmProperty,
2837        "AUTO_INCREMENT": AutoIncrementProperty,
2838        "CHARACTER SET": CharacterSetProperty,
2839        "CLUSTERED_BY": ClusteredByProperty,
2840        "COLLATE": CollateProperty,
2841        "COMMENT": SchemaCommentProperty,
2842        "DEFINER": DefinerProperty,
2843        "DISTKEY": DistKeyProperty,
2844        "DISTSTYLE": DistStyleProperty,
2845        "ENGINE": EngineProperty,
2846        "EXECUTE AS": ExecuteAsProperty,
2847        "FORMAT": FileFormatProperty,
2848        "LANGUAGE": LanguageProperty,
2849        "LOCATION": LocationProperty,
2850        "LOCK": LockProperty,
2851        "PARTITIONED_BY": PartitionedByProperty,
2852        "RETURNS": ReturnsProperty,
2853        "ROW_FORMAT": RowFormatProperty,
2854        "SORTKEY": SortKeyProperty,
2855    }
2856
2857    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2858
2859    # CREATE property locations
2860    # Form: schema specified
2861    #   create [POST_CREATE]
2862    #     table a [POST_NAME]
2863    #     (b int) [POST_SCHEMA]
2864    #     with ([POST_WITH])
2865    #     index (b) [POST_INDEX]
2866    #
2867    # Form: alias selection
2868    #   create [POST_CREATE]
2869    #     table a [POST_NAME]
2870    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2871    #     index (c) [POST_INDEX]
2872    class Location(AutoName):
2873        POST_CREATE = auto()
2874        POST_NAME = auto()
2875        POST_SCHEMA = auto()
2876        POST_WITH = auto()
2877        POST_ALIAS = auto()
2878        POST_EXPRESSION = auto()
2879        POST_INDEX = auto()
2880        UNSUPPORTED = auto()
2881
2882    @classmethod
2883    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2884        expressions = []
2885        for key, value in properties_dict.items():
2886            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2887            if property_cls:
2888                expressions.append(property_cls(this=convert(value)))
2889            else:
2890                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2891
2892        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, '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'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class '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'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2882    @classmethod
2883    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2884        expressions = []
2885        for key, value in properties_dict.items():
2886            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2887            if property_cls:
2888                expressions.append(property_cls(this=convert(value)))
2889            else:
2890                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2891
2892        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2872    class Location(AutoName):
2873        POST_CREATE = auto()
2874        POST_NAME = auto()
2875        POST_SCHEMA = auto()
2876        POST_WITH = auto()
2877        POST_ALIAS = auto()
2878        POST_EXPRESSION = auto()
2879        POST_INDEX = auto()
2880        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'>
Inherited Members
enum.Enum
name
value
class Qualify(Expression):
2895class Qualify(Expression):
2896    pass
key = 'qualify'
class InputOutputFormat(Expression):
2899class InputOutputFormat(Expression):
2900    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2904class Return(Expression):
2905    pass
key = 'return'
class Reference(Expression):
2908class Reference(Expression):
2909    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2912class Tuple(Expression):
2913    arg_types = {"expressions": False}
2914
2915    def isin(
2916        self,
2917        *expressions: t.Any,
2918        query: t.Optional[ExpOrStr] = None,
2919        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2920        copy: bool = True,
2921        **opts,
2922    ) -> In:
2923        return In(
2924            this=maybe_copy(self, copy),
2925            expressions=[convert(e, copy=copy) for e in expressions],
2926            query=maybe_parse(query, copy=copy, **opts) if query else None,
2927            unnest=(
2928                Unnest(
2929                    expressions=[
2930                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2931                        for e in ensure_list(unnest)
2932                    ]
2933                )
2934                if unnest
2935                else None
2936            ),
2937        )
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:
2915    def isin(
2916        self,
2917        *expressions: t.Any,
2918        query: t.Optional[ExpOrStr] = None,
2919        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2920        copy: bool = True,
2921        **opts,
2922    ) -> In:
2923        return In(
2924            this=maybe_copy(self, copy),
2925            expressions=[convert(e, copy=copy) for e in expressions],
2926            query=maybe_parse(query, copy=copy, **opts) if query else None,
2927            unnest=(
2928                Unnest(
2929                    expressions=[
2930                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2931                        for e in ensure_list(unnest)
2932                    ]
2933                )
2934                if unnest
2935                else None
2936            ),
2937        )
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):
2968class QueryOption(Expression):
2969    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2973class WithTableHint(Expression):
2974    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2978class IndexTableHint(Expression):
2979    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2983class HistoricalData(Expression):
2984    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2987class Table(Expression):
2988    arg_types = {
2989        "this": False,
2990        "alias": False,
2991        "db": False,
2992        "catalog": False,
2993        "laterals": False,
2994        "joins": False,
2995        "pivots": False,
2996        "hints": False,
2997        "system_time": False,
2998        "version": False,
2999        "format": False,
3000        "pattern": False,
3001        "ordinality": False,
3002        "when": False,
3003        "only": False,
3004        "partition": False,
3005    }
3006
3007    @property
3008    def name(self) -> str:
3009        if isinstance(self.this, Func):
3010            return ""
3011        return self.this.name
3012
3013    @property
3014    def db(self) -> str:
3015        return self.text("db")
3016
3017    @property
3018    def catalog(self) -> str:
3019        return self.text("catalog")
3020
3021    @property
3022    def selects(self) -> t.List[Expression]:
3023        return []
3024
3025    @property
3026    def named_selects(self) -> t.List[str]:
3027        return []
3028
3029    @property
3030    def parts(self) -> t.List[Expression]:
3031        """Return the parts of a table in order catalog, db, table."""
3032        parts: t.List[Expression] = []
3033
3034        for arg in ("catalog", "db", "this"):
3035            part = self.args.get(arg)
3036
3037            if isinstance(part, Dot):
3038                parts.extend(part.flatten())
3039            elif isinstance(part, Expression):
3040                parts.append(part)
3041
3042        return parts
3043
3044    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3045        parts = self.parts
3046        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3047        alias = self.args.get("alias")
3048        if alias:
3049            col = alias_(col, alias.this, copy=copy)
3050        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}
name: str
3007    @property
3008    def name(self) -> str:
3009        if isinstance(self.this, Func):
3010            return ""
3011        return self.this.name
db: str
3013    @property
3014    def db(self) -> str:
3015        return self.text("db")
catalog: str
3017    @property
3018    def catalog(self) -> str:
3019        return self.text("catalog")
selects: List[Expression]
3021    @property
3022    def selects(self) -> t.List[Expression]:
3023        return []
named_selects: List[str]
3025    @property
3026    def named_selects(self) -> t.List[str]:
3027        return []
parts: List[Expression]
3029    @property
3030    def parts(self) -> t.List[Expression]:
3031        """Return the parts of a table in order catalog, db, table."""
3032        parts: t.List[Expression] = []
3033
3034        for arg in ("catalog", "db", "this"):
3035            part = self.args.get(arg)
3036
3037            if isinstance(part, Dot):
3038                parts.extend(part.flatten())
3039            elif isinstance(part, Expression):
3040                parts.append(part)
3041
3042        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3044    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3045        parts = self.parts
3046        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3047        alias = self.args.get("alias")
3048        if alias:
3049            col = alias_(col, alias.this, copy=copy)
3050        return col
key = 'table'
class Union(Query):
3053class Union(Query):
3054    arg_types = {
3055        "with": False,
3056        "this": True,
3057        "expression": True,
3058        "distinct": False,
3059        "by_name": False,
3060        **QUERY_MODIFIERS,
3061    }
3062
3063    def select(
3064        self,
3065        *expressions: t.Optional[ExpOrStr],
3066        append: bool = True,
3067        dialect: DialectType = None,
3068        copy: bool = True,
3069        **opts,
3070    ) -> Union:
3071        this = maybe_copy(self, copy)
3072        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3073        this.expression.unnest().select(
3074            *expressions, append=append, dialect=dialect, copy=False, **opts
3075        )
3076        return this
3077
3078    @property
3079    def named_selects(self) -> t.List[str]:
3080        return self.this.unnest().named_selects
3081
3082    @property
3083    def is_star(self) -> bool:
3084        return self.this.is_star or self.expression.is_star
3085
3086    @property
3087    def selects(self) -> t.List[Expression]:
3088        return self.this.unnest().selects
3089
3090    @property
3091    def left(self) -> Expression:
3092        return self.this
3093
3094    @property
3095    def right(self) -> Expression:
3096        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
3063    def select(
3064        self,
3065        *expressions: t.Optional[ExpOrStr],
3066        append: bool = True,
3067        dialect: DialectType = None,
3068        copy: bool = True,
3069        **opts,
3070    ) -> Union:
3071        this = maybe_copy(self, copy)
3072        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3073        this.expression.unnest().select(
3074            *expressions, append=append, dialect=dialect, copy=False, **opts
3075        )
3076        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]
3078    @property
3079    def named_selects(self) -> t.List[str]:
3080        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3082    @property
3083    def is_star(self) -> bool:
3084        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3086    @property
3087    def selects(self) -> t.List[Expression]:
3088        return self.this.unnest().selects

Returns the query's projections.

left: Expression
3090    @property
3091    def left(self) -> Expression:
3092        return self.this
right: Expression
3094    @property
3095    def right(self) -> Expression:
3096        return self.expression
key = 'union'
class Except(Union):
3099class Except(Union):
3100    pass
key = 'except'
class Intersect(Union):
3103class Intersect(Union):
3104    pass
key = 'intersect'
class Unnest(UDTF):
3107class Unnest(UDTF):
3108    arg_types = {
3109        "expressions": True,
3110        "alias": False,
3111        "offset": False,
3112    }
3113
3114    @property
3115    def selects(self) -> t.List[Expression]:
3116        columns = super().selects
3117        offset = self.args.get("offset")
3118        if offset:
3119            columns = columns + [to_identifier("offset") if offset is True else offset]
3120        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
3114    @property
3115    def selects(self) -> t.List[Expression]:
3116        columns = super().selects
3117        offset = self.args.get("offset")
3118        if offset:
3119            columns = columns + [to_identifier("offset") if offset is True else offset]
3120        return columns
key = 'unnest'
class Update(Expression):
3123class Update(Expression):
3124    arg_types = {
3125        "with": False,
3126        "this": False,
3127        "expressions": True,
3128        "from": False,
3129        "where": False,
3130        "returning": False,
3131        "order": False,
3132        "limit": False,
3133    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
3136class Values(UDTF):
3137    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3140class Var(Expression):
3141    pass
key = 'var'
class Version(Expression):
3144class Version(Expression):
3145    """
3146    Time travel, iceberg, bigquery etc
3147    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3148    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3149    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3150    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3151    this is either TIMESTAMP or VERSION
3152    kind is ("AS OF", "BETWEEN")
3153    """
3154
3155    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3158class Schema(Expression):
3159    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3164class Lock(Expression):
3165    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3168class Select(Query):
3169    arg_types = {
3170        "with": False,
3171        "kind": False,
3172        "expressions": False,
3173        "hint": False,
3174        "distinct": False,
3175        "into": False,
3176        "from": False,
3177        **QUERY_MODIFIERS,
3178    }
3179
3180    def from_(
3181        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3182    ) -> Select:
3183        """
3184        Set the FROM expression.
3185
3186        Example:
3187            >>> Select().from_("tbl").select("x").sql()
3188            'SELECT x FROM tbl'
3189
3190        Args:
3191            expression : the SQL code strings to parse.
3192                If a `From` instance is passed, this is used as-is.
3193                If another `Expression` instance is passed, it will be wrapped in a `From`.
3194            dialect: the dialect used to parse the input expression.
3195            copy: if `False`, modify this expression instance in-place.
3196            opts: other options to use to parse the input expressions.
3197
3198        Returns:
3199            The modified Select expression.
3200        """
3201        return _apply_builder(
3202            expression=expression,
3203            instance=self,
3204            arg="from",
3205            into=From,
3206            prefix="FROM",
3207            dialect=dialect,
3208            copy=copy,
3209            **opts,
3210        )
3211
3212    def group_by(
3213        self,
3214        *expressions: t.Optional[ExpOrStr],
3215        append: bool = True,
3216        dialect: DialectType = None,
3217        copy: bool = True,
3218        **opts,
3219    ) -> Select:
3220        """
3221        Set the GROUP BY expression.
3222
3223        Example:
3224            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3225            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3226
3227        Args:
3228            *expressions: the SQL code strings to parse.
3229                If a `Group` instance is passed, this is used as-is.
3230                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3231                If nothing is passed in then a group by is not applied to the expression
3232            append: if `True`, add to any existing expressions.
3233                Otherwise, this flattens all the `Group` expression into a single expression.
3234            dialect: the dialect used to parse the input expression.
3235            copy: if `False`, modify this expression instance in-place.
3236            opts: other options to use to parse the input expressions.
3237
3238        Returns:
3239            The modified Select expression.
3240        """
3241        if not expressions:
3242            return self if not copy else self.copy()
3243
3244        return _apply_child_list_builder(
3245            *expressions,
3246            instance=self,
3247            arg="group",
3248            append=append,
3249            copy=copy,
3250            prefix="GROUP BY",
3251            into=Group,
3252            dialect=dialect,
3253            **opts,
3254        )
3255
3256    def sort_by(
3257        self,
3258        *expressions: t.Optional[ExpOrStr],
3259        append: bool = True,
3260        dialect: DialectType = None,
3261        copy: bool = True,
3262        **opts,
3263    ) -> Select:
3264        """
3265        Set the SORT BY expression.
3266
3267        Example:
3268            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3269            'SELECT x FROM tbl SORT BY x DESC'
3270
3271        Args:
3272            *expressions: the SQL code strings to parse.
3273                If a `Group` instance is passed, this is used as-is.
3274                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3275            append: if `True`, add to any existing expressions.
3276                Otherwise, this flattens all the `Order` expression into a single expression.
3277            dialect: the dialect used to parse the input expression.
3278            copy: if `False`, modify this expression instance in-place.
3279            opts: other options to use to parse the input expressions.
3280
3281        Returns:
3282            The modified Select expression.
3283        """
3284        return _apply_child_list_builder(
3285            *expressions,
3286            instance=self,
3287            arg="sort",
3288            append=append,
3289            copy=copy,
3290            prefix="SORT BY",
3291            into=Sort,
3292            dialect=dialect,
3293            **opts,
3294        )
3295
3296    def cluster_by(
3297        self,
3298        *expressions: t.Optional[ExpOrStr],
3299        append: bool = True,
3300        dialect: DialectType = None,
3301        copy: bool = True,
3302        **opts,
3303    ) -> Select:
3304        """
3305        Set the CLUSTER BY expression.
3306
3307        Example:
3308            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3309            'SELECT x FROM tbl CLUSTER BY x DESC'
3310
3311        Args:
3312            *expressions: the SQL code strings to parse.
3313                If a `Group` instance is passed, this is used as-is.
3314                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3315            append: if `True`, add to any existing expressions.
3316                Otherwise, this flattens all the `Order` expression into a single expression.
3317            dialect: the dialect used to parse the input expression.
3318            copy: if `False`, modify this expression instance in-place.
3319            opts: other options to use to parse the input expressions.
3320
3321        Returns:
3322            The modified Select expression.
3323        """
3324        return _apply_child_list_builder(
3325            *expressions,
3326            instance=self,
3327            arg="cluster",
3328            append=append,
3329            copy=copy,
3330            prefix="CLUSTER BY",
3331            into=Cluster,
3332            dialect=dialect,
3333            **opts,
3334        )
3335
3336    def select(
3337        self,
3338        *expressions: t.Optional[ExpOrStr],
3339        append: bool = True,
3340        dialect: DialectType = None,
3341        copy: bool = True,
3342        **opts,
3343    ) -> Select:
3344        return _apply_list_builder(
3345            *expressions,
3346            instance=self,
3347            arg="expressions",
3348            append=append,
3349            dialect=dialect,
3350            into=Expression,
3351            copy=copy,
3352            **opts,
3353        )
3354
3355    def lateral(
3356        self,
3357        *expressions: t.Optional[ExpOrStr],
3358        append: bool = True,
3359        dialect: DialectType = None,
3360        copy: bool = True,
3361        **opts,
3362    ) -> Select:
3363        """
3364        Append to or set the LATERAL expressions.
3365
3366        Example:
3367            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3368            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3369
3370        Args:
3371            *expressions: the SQL code strings to parse.
3372                If an `Expression` instance is passed, it will be used as-is.
3373            append: if `True`, add to any existing expressions.
3374                Otherwise, this resets the expressions.
3375            dialect: the dialect used to parse the input expressions.
3376            copy: if `False`, modify this expression instance in-place.
3377            opts: other options to use to parse the input expressions.
3378
3379        Returns:
3380            The modified Select expression.
3381        """
3382        return _apply_list_builder(
3383            *expressions,
3384            instance=self,
3385            arg="laterals",
3386            append=append,
3387            into=Lateral,
3388            prefix="LATERAL VIEW",
3389            dialect=dialect,
3390            copy=copy,
3391            **opts,
3392        )
3393
3394    def join(
3395        self,
3396        expression: ExpOrStr,
3397        on: t.Optional[ExpOrStr] = None,
3398        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3399        append: bool = True,
3400        join_type: t.Optional[str] = None,
3401        join_alias: t.Optional[Identifier | str] = None,
3402        dialect: DialectType = None,
3403        copy: bool = True,
3404        **opts,
3405    ) -> Select:
3406        """
3407        Append to or set the JOIN expressions.
3408
3409        Example:
3410            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3411            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3412
3413            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3414            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3415
3416            Use `join_type` to change the type of join:
3417
3418            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3419            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3420
3421        Args:
3422            expression: the SQL code string to parse.
3423                If an `Expression` instance is passed, it will be used as-is.
3424            on: optionally specify the join "on" criteria as a SQL string.
3425                If an `Expression` instance is passed, it will be used as-is.
3426            using: optionally specify the join "using" criteria as a SQL string.
3427                If an `Expression` instance is passed, it will be used as-is.
3428            append: if `True`, add to any existing expressions.
3429                Otherwise, this resets the expressions.
3430            join_type: if set, alter the parsed join type.
3431            join_alias: an optional alias for the joined source.
3432            dialect: the dialect used to parse the input expressions.
3433            copy: if `False`, modify this expression instance in-place.
3434            opts: other options to use to parse the input expressions.
3435
3436        Returns:
3437            Select: the modified expression.
3438        """
3439        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3440
3441        try:
3442            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3443        except ParseError:
3444            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3445
3446        join = expression if isinstance(expression, Join) else Join(this=expression)
3447
3448        if isinstance(join.this, Select):
3449            join.this.replace(join.this.subquery())
3450
3451        if join_type:
3452            method: t.Optional[Token]
3453            side: t.Optional[Token]
3454            kind: t.Optional[Token]
3455
3456            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3457
3458            if method:
3459                join.set("method", method.text)
3460            if side:
3461                join.set("side", side.text)
3462            if kind:
3463                join.set("kind", kind.text)
3464
3465        if on:
3466            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3467            join.set("on", on)
3468
3469        if using:
3470            join = _apply_list_builder(
3471                *ensure_list(using),
3472                instance=join,
3473                arg="using",
3474                append=append,
3475                copy=copy,
3476                into=Identifier,
3477                **opts,
3478            )
3479
3480        if join_alias:
3481            join.set("this", alias_(join.this, join_alias, table=True))
3482
3483        return _apply_list_builder(
3484            join,
3485            instance=self,
3486            arg="joins",
3487            append=append,
3488            copy=copy,
3489            **opts,
3490        )
3491
3492    def where(
3493        self,
3494        *expressions: t.Optional[ExpOrStr],
3495        append: bool = True,
3496        dialect: DialectType = None,
3497        copy: bool = True,
3498        **opts,
3499    ) -> Select:
3500        """
3501        Append to or set the WHERE expressions.
3502
3503        Example:
3504            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3505            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3506
3507        Args:
3508            *expressions: the SQL code strings to parse.
3509                If an `Expression` instance is passed, it will be used as-is.
3510                Multiple expressions are combined with an AND operator.
3511            append: if `True`, AND the new expressions to any existing expression.
3512                Otherwise, this resets the expression.
3513            dialect: the dialect used to parse the input expressions.
3514            copy: if `False`, modify this expression instance in-place.
3515            opts: other options to use to parse the input expressions.
3516
3517        Returns:
3518            Select: the modified expression.
3519        """
3520        return _apply_conjunction_builder(
3521            *expressions,
3522            instance=self,
3523            arg="where",
3524            append=append,
3525            into=Where,
3526            dialect=dialect,
3527            copy=copy,
3528            **opts,
3529        )
3530
3531    def having(
3532        self,
3533        *expressions: t.Optional[ExpOrStr],
3534        append: bool = True,
3535        dialect: DialectType = None,
3536        copy: bool = True,
3537        **opts,
3538    ) -> Select:
3539        """
3540        Append to or set the HAVING expressions.
3541
3542        Example:
3543            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3544            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3545
3546        Args:
3547            *expressions: the SQL code strings to parse.
3548                If an `Expression` instance is passed, it will be used as-is.
3549                Multiple expressions are combined with an AND operator.
3550            append: if `True`, AND the new expressions to any existing expression.
3551                Otherwise, this resets the expression.
3552            dialect: the dialect used to parse the input expressions.
3553            copy: if `False`, modify this expression instance in-place.
3554            opts: other options to use to parse the input expressions.
3555
3556        Returns:
3557            The modified Select expression.
3558        """
3559        return _apply_conjunction_builder(
3560            *expressions,
3561            instance=self,
3562            arg="having",
3563            append=append,
3564            into=Having,
3565            dialect=dialect,
3566            copy=copy,
3567            **opts,
3568        )
3569
3570    def window(
3571        self,
3572        *expressions: t.Optional[ExpOrStr],
3573        append: bool = True,
3574        dialect: DialectType = None,
3575        copy: bool = True,
3576        **opts,
3577    ) -> Select:
3578        return _apply_list_builder(
3579            *expressions,
3580            instance=self,
3581            arg="windows",
3582            append=append,
3583            into=Window,
3584            dialect=dialect,
3585            copy=copy,
3586            **opts,
3587        )
3588
3589    def qualify(
3590        self,
3591        *expressions: t.Optional[ExpOrStr],
3592        append: bool = True,
3593        dialect: DialectType = None,
3594        copy: bool = True,
3595        **opts,
3596    ) -> Select:
3597        return _apply_conjunction_builder(
3598            *expressions,
3599            instance=self,
3600            arg="qualify",
3601            append=append,
3602            into=Qualify,
3603            dialect=dialect,
3604            copy=copy,
3605            **opts,
3606        )
3607
3608    def distinct(
3609        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3610    ) -> Select:
3611        """
3612        Set the OFFSET expression.
3613
3614        Example:
3615            >>> Select().from_("tbl").select("x").distinct().sql()
3616            'SELECT DISTINCT x FROM tbl'
3617
3618        Args:
3619            ons: the expressions to distinct on
3620            distinct: whether the Select should be distinct
3621            copy: if `False`, modify this expression instance in-place.
3622
3623        Returns:
3624            Select: the modified expression.
3625        """
3626        instance = maybe_copy(self, copy)
3627        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3628        instance.set("distinct", Distinct(on=on) if distinct else None)
3629        return instance
3630
3631    def ctas(
3632        self,
3633        table: ExpOrStr,
3634        properties: t.Optional[t.Dict] = None,
3635        dialect: DialectType = None,
3636        copy: bool = True,
3637        **opts,
3638    ) -> Create:
3639        """
3640        Convert this expression to a CREATE TABLE AS statement.
3641
3642        Example:
3643            >>> Select().select("*").from_("tbl").ctas("x").sql()
3644            'CREATE TABLE x AS SELECT * FROM tbl'
3645
3646        Args:
3647            table: the SQL code string to parse as the table name.
3648                If another `Expression` instance is passed, it will be used as-is.
3649            properties: an optional mapping of table properties
3650            dialect: the dialect used to parse the input table.
3651            copy: if `False`, modify this expression instance in-place.
3652            opts: other options to use to parse the input table.
3653
3654        Returns:
3655            The new Create expression.
3656        """
3657        instance = maybe_copy(self, copy)
3658        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3659
3660        properties_expression = None
3661        if properties:
3662            properties_expression = Properties.from_dict(properties)
3663
3664        return Create(
3665            this=table_expression,
3666            kind="TABLE",
3667            expression=instance,
3668            properties=properties_expression,
3669        )
3670
3671    def lock(self, update: bool = True, copy: bool = True) -> Select:
3672        """
3673        Set the locking read mode for this expression.
3674
3675        Examples:
3676            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3677            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3678
3679            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3680            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3681
3682        Args:
3683            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3684            copy: if `False`, modify this expression instance in-place.
3685
3686        Returns:
3687            The modified expression.
3688        """
3689        inst = maybe_copy(self, copy)
3690        inst.set("locks", [Lock(update=update)])
3691
3692        return inst
3693
3694    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3695        """
3696        Set hints for this expression.
3697
3698        Examples:
3699            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3700            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3701
3702        Args:
3703            hints: The SQL code strings to parse as the hints.
3704                If an `Expression` instance is passed, it will be used as-is.
3705            dialect: The dialect used to parse the hints.
3706            copy: If `False`, modify this expression instance in-place.
3707
3708        Returns:
3709            The modified expression.
3710        """
3711        inst = maybe_copy(self, copy)
3712        inst.set(
3713            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3714        )
3715
3716        return inst
3717
3718    @property
3719    def named_selects(self) -> t.List[str]:
3720        return [e.output_name for e in self.expressions if e.alias_or_name]
3721
3722    @property
3723    def is_star(self) -> bool:
3724        return any(expression.is_star for expression in self.expressions)
3725
3726    @property
3727    def selects(self) -> t.List[Expression]:
3728        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3180    def from_(
3181        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3182    ) -> Select:
3183        """
3184        Set the FROM expression.
3185
3186        Example:
3187            >>> Select().from_("tbl").select("x").sql()
3188            'SELECT x FROM tbl'
3189
3190        Args:
3191            expression : the SQL code strings to parse.
3192                If a `From` instance is passed, this is used as-is.
3193                If another `Expression` instance is passed, it will be wrapped in a `From`.
3194            dialect: the dialect used to parse the input expression.
3195            copy: if `False`, modify this expression instance in-place.
3196            opts: other options to use to parse the input expressions.
3197
3198        Returns:
3199            The modified Select expression.
3200        """
3201        return _apply_builder(
3202            expression=expression,
3203            instance=self,
3204            arg="from",
3205            into=From,
3206            prefix="FROM",
3207            dialect=dialect,
3208            copy=copy,
3209            **opts,
3210        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3212    def group_by(
3213        self,
3214        *expressions: t.Optional[ExpOrStr],
3215        append: bool = True,
3216        dialect: DialectType = None,
3217        copy: bool = True,
3218        **opts,
3219    ) -> Select:
3220        """
3221        Set the GROUP BY expression.
3222
3223        Example:
3224            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3225            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3226
3227        Args:
3228            *expressions: the SQL code strings to parse.
3229                If a `Group` instance is passed, this is used as-is.
3230                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3231                If nothing is passed in then a group by is not applied to the expression
3232            append: if `True`, add to any existing expressions.
3233                Otherwise, this flattens all the `Group` expression into a single expression.
3234            dialect: the dialect used to parse the input expression.
3235            copy: if `False`, modify this expression instance in-place.
3236            opts: other options to use to parse the input expressions.
3237
3238        Returns:
3239            The modified Select expression.
3240        """
3241        if not expressions:
3242            return self if not copy else self.copy()
3243
3244        return _apply_child_list_builder(
3245            *expressions,
3246            instance=self,
3247            arg="group",
3248            append=append,
3249            copy=copy,
3250            prefix="GROUP BY",
3251            into=Group,
3252            dialect=dialect,
3253            **opts,
3254        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3256    def sort_by(
3257        self,
3258        *expressions: t.Optional[ExpOrStr],
3259        append: bool = True,
3260        dialect: DialectType = None,
3261        copy: bool = True,
3262        **opts,
3263    ) -> Select:
3264        """
3265        Set the SORT BY expression.
3266
3267        Example:
3268            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3269            'SELECT x FROM tbl SORT BY x DESC'
3270
3271        Args:
3272            *expressions: the SQL code strings to parse.
3273                If a `Group` instance is passed, this is used as-is.
3274                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3275            append: if `True`, add to any existing expressions.
3276                Otherwise, this flattens all the `Order` expression into a single expression.
3277            dialect: the dialect used to parse the input expression.
3278            copy: if `False`, modify this expression instance in-place.
3279            opts: other options to use to parse the input expressions.
3280
3281        Returns:
3282            The modified Select expression.
3283        """
3284        return _apply_child_list_builder(
3285            *expressions,
3286            instance=self,
3287            arg="sort",
3288            append=append,
3289            copy=copy,
3290            prefix="SORT BY",
3291            into=Sort,
3292            dialect=dialect,
3293            **opts,
3294        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3296    def cluster_by(
3297        self,
3298        *expressions: t.Optional[ExpOrStr],
3299        append: bool = True,
3300        dialect: DialectType = None,
3301        copy: bool = True,
3302        **opts,
3303    ) -> Select:
3304        """
3305        Set the CLUSTER BY expression.
3306
3307        Example:
3308            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3309            'SELECT x FROM tbl CLUSTER BY x DESC'
3310
3311        Args:
3312            *expressions: the SQL code strings to parse.
3313                If a `Group` instance is passed, this is used as-is.
3314                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3315            append: if `True`, add to any existing expressions.
3316                Otherwise, this flattens all the `Order` expression into a single expression.
3317            dialect: the dialect used to parse the input expression.
3318            copy: if `False`, modify this expression instance in-place.
3319            opts: other options to use to parse the input expressions.
3320
3321        Returns:
3322            The modified Select expression.
3323        """
3324        return _apply_child_list_builder(
3325            *expressions,
3326            instance=self,
3327            arg="cluster",
3328            append=append,
3329            copy=copy,
3330            prefix="CLUSTER BY",
3331            into=Cluster,
3332            dialect=dialect,
3333            **opts,
3334        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3336    def select(
3337        self,
3338        *expressions: t.Optional[ExpOrStr],
3339        append: bool = True,
3340        dialect: DialectType = None,
3341        copy: bool = True,
3342        **opts,
3343    ) -> Select:
3344        return _apply_list_builder(
3345            *expressions,
3346            instance=self,
3347            arg="expressions",
3348            append=append,
3349            dialect=dialect,
3350            into=Expression,
3351            copy=copy,
3352            **opts,
3353        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3355    def lateral(
3356        self,
3357        *expressions: t.Optional[ExpOrStr],
3358        append: bool = True,
3359        dialect: DialectType = None,
3360        copy: bool = True,
3361        **opts,
3362    ) -> Select:
3363        """
3364        Append to or set the LATERAL expressions.
3365
3366        Example:
3367            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3368            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3369
3370        Args:
3371            *expressions: the SQL code strings to parse.
3372                If an `Expression` instance is passed, it will be used as-is.
3373            append: if `True`, add to any existing expressions.
3374                Otherwise, this resets the expressions.
3375            dialect: the dialect used to parse the input expressions.
3376            copy: if `False`, modify this expression instance in-place.
3377            opts: other options to use to parse the input expressions.
3378
3379        Returns:
3380            The modified Select expression.
3381        """
3382        return _apply_list_builder(
3383            *expressions,
3384            instance=self,
3385            arg="laterals",
3386            append=append,
3387            into=Lateral,
3388            prefix="LATERAL VIEW",
3389            dialect=dialect,
3390            copy=copy,
3391            **opts,
3392        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3394    def join(
3395        self,
3396        expression: ExpOrStr,
3397        on: t.Optional[ExpOrStr] = None,
3398        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3399        append: bool = True,
3400        join_type: t.Optional[str] = None,
3401        join_alias: t.Optional[Identifier | str] = None,
3402        dialect: DialectType = None,
3403        copy: bool = True,
3404        **opts,
3405    ) -> Select:
3406        """
3407        Append to or set the JOIN expressions.
3408
3409        Example:
3410            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3411            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3412
3413            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3414            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3415
3416            Use `join_type` to change the type of join:
3417
3418            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3419            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3420
3421        Args:
3422            expression: the SQL code string to parse.
3423                If an `Expression` instance is passed, it will be used as-is.
3424            on: optionally specify the join "on" criteria as a SQL string.
3425                If an `Expression` instance is passed, it will be used as-is.
3426            using: optionally specify the join "using" criteria as a SQL string.
3427                If an `Expression` instance is passed, it will be used as-is.
3428            append: if `True`, add to any existing expressions.
3429                Otherwise, this resets the expressions.
3430            join_type: if set, alter the parsed join type.
3431            join_alias: an optional alias for the joined source.
3432            dialect: the dialect used to parse the input expressions.
3433            copy: if `False`, modify this expression instance in-place.
3434            opts: other options to use to parse the input expressions.
3435
3436        Returns:
3437            Select: the modified expression.
3438        """
3439        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3440
3441        try:
3442            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3443        except ParseError:
3444            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3445
3446        join = expression if isinstance(expression, Join) else Join(this=expression)
3447
3448        if isinstance(join.this, Select):
3449            join.this.replace(join.this.subquery())
3450
3451        if join_type:
3452            method: t.Optional[Token]
3453            side: t.Optional[Token]
3454            kind: t.Optional[Token]
3455
3456            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3457
3458            if method:
3459                join.set("method", method.text)
3460            if side:
3461                join.set("side", side.text)
3462            if kind:
3463                join.set("kind", kind.text)
3464
3465        if on:
3466            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3467            join.set("on", on)
3468
3469        if using:
3470            join = _apply_list_builder(
3471                *ensure_list(using),
3472                instance=join,
3473                arg="using",
3474                append=append,
3475                copy=copy,
3476                into=Identifier,
3477                **opts,
3478            )
3479
3480        if join_alias:
3481            join.set("this", alias_(join.this, join_alias, table=True))
3482
3483        return _apply_list_builder(
3484            join,
3485            instance=self,
3486            arg="joins",
3487            append=append,
3488            copy=copy,
3489            **opts,
3490        )

Append to or set the JOIN expressions.

Example:
>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
>>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
'SELECT 1 FROM a JOIN b USING (x, y, z)'

Use join_type to change the type of join:

>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • join_type: if set, alter the parsed join type.
  • join_alias: an optional alias for the joined source.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3492    def where(
3493        self,
3494        *expressions: t.Optional[ExpOrStr],
3495        append: bool = True,
3496        dialect: DialectType = None,
3497        copy: bool = True,
3498        **opts,
3499    ) -> Select:
3500        """
3501        Append to or set the WHERE expressions.
3502
3503        Example:
3504            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3505            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3506
3507        Args:
3508            *expressions: the SQL code strings to parse.
3509                If an `Expression` instance is passed, it will be used as-is.
3510                Multiple expressions are combined with an AND operator.
3511            append: if `True`, AND the new expressions to any existing expression.
3512                Otherwise, this resets the expression.
3513            dialect: the dialect used to parse the input expressions.
3514            copy: if `False`, modify this expression instance in-place.
3515            opts: other options to use to parse the input expressions.
3516
3517        Returns:
3518            Select: the modified expression.
3519        """
3520        return _apply_conjunction_builder(
3521            *expressions,
3522            instance=self,
3523            arg="where",
3524            append=append,
3525            into=Where,
3526            dialect=dialect,
3527            copy=copy,
3528            **opts,
3529        )

Append to or set the WHERE expressions.

Example:
>>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
"SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3531    def having(
3532        self,
3533        *expressions: t.Optional[ExpOrStr],
3534        append: bool = True,
3535        dialect: DialectType = None,
3536        copy: bool = True,
3537        **opts,
3538    ) -> Select:
3539        """
3540        Append to or set the HAVING expressions.
3541
3542        Example:
3543            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3544            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3545
3546        Args:
3547            *expressions: the SQL code strings to parse.
3548                If an `Expression` instance is passed, it will be used as-is.
3549                Multiple expressions are combined with an AND operator.
3550            append: if `True`, AND the new expressions to any existing expression.
3551                Otherwise, this resets the expression.
3552            dialect: the dialect used to parse the input expressions.
3553            copy: if `False`, modify this expression instance in-place.
3554            opts: other options to use to parse the input expressions.
3555
3556        Returns:
3557            The modified Select expression.
3558        """
3559        return _apply_conjunction_builder(
3560            *expressions,
3561            instance=self,
3562            arg="having",
3563            append=append,
3564            into=Having,
3565            dialect=dialect,
3566            copy=copy,
3567            **opts,
3568        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3570    def window(
3571        self,
3572        *expressions: t.Optional[ExpOrStr],
3573        append: bool = True,
3574        dialect: DialectType = None,
3575        copy: bool = True,
3576        **opts,
3577    ) -> Select:
3578        return _apply_list_builder(
3579            *expressions,
3580            instance=self,
3581            arg="windows",
3582            append=append,
3583            into=Window,
3584            dialect=dialect,
3585            copy=copy,
3586            **opts,
3587        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3589    def qualify(
3590        self,
3591        *expressions: t.Optional[ExpOrStr],
3592        append: bool = True,
3593        dialect: DialectType = None,
3594        copy: bool = True,
3595        **opts,
3596    ) -> Select:
3597        return _apply_conjunction_builder(
3598            *expressions,
3599            instance=self,
3600            arg="qualify",
3601            append=append,
3602            into=Qualify,
3603            dialect=dialect,
3604            copy=copy,
3605            **opts,
3606        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3608    def distinct(
3609        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3610    ) -> Select:
3611        """
3612        Set the OFFSET expression.
3613
3614        Example:
3615            >>> Select().from_("tbl").select("x").distinct().sql()
3616            'SELECT DISTINCT x FROM tbl'
3617
3618        Args:
3619            ons: the expressions to distinct on
3620            distinct: whether the Select should be distinct
3621            copy: if `False`, modify this expression instance in-place.
3622
3623        Returns:
3624            Select: the modified expression.
3625        """
3626        instance = maybe_copy(self, copy)
3627        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3628        instance.set("distinct", Distinct(on=on) if distinct else None)
3629        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
3631    def ctas(
3632        self,
3633        table: ExpOrStr,
3634        properties: t.Optional[t.Dict] = None,
3635        dialect: DialectType = None,
3636        copy: bool = True,
3637        **opts,
3638    ) -> Create:
3639        """
3640        Convert this expression to a CREATE TABLE AS statement.
3641
3642        Example:
3643            >>> Select().select("*").from_("tbl").ctas("x").sql()
3644            'CREATE TABLE x AS SELECT * FROM tbl'
3645
3646        Args:
3647            table: the SQL code string to parse as the table name.
3648                If another `Expression` instance is passed, it will be used as-is.
3649            properties: an optional mapping of table properties
3650            dialect: the dialect used to parse the input table.
3651            copy: if `False`, modify this expression instance in-place.
3652            opts: other options to use to parse the input table.
3653
3654        Returns:
3655            The new Create expression.
3656        """
3657        instance = maybe_copy(self, copy)
3658        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3659
3660        properties_expression = None
3661        if properties:
3662            properties_expression = Properties.from_dict(properties)
3663
3664        return Create(
3665            this=table_expression,
3666            kind="TABLE",
3667            expression=instance,
3668            properties=properties_expression,
3669        )

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:
3671    def lock(self, update: bool = True, copy: bool = True) -> Select:
3672        """
3673        Set the locking read mode for this expression.
3674
3675        Examples:
3676            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3677            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3678
3679            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3680            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3681
3682        Args:
3683            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3684            copy: if `False`, modify this expression instance in-place.
3685
3686        Returns:
3687            The modified expression.
3688        """
3689        inst = maybe_copy(self, copy)
3690        inst.set("locks", [Lock(update=update)])
3691
3692        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
3694    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3695        """
3696        Set hints for this expression.
3697
3698        Examples:
3699            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3700            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3701
3702        Args:
3703            hints: The SQL code strings to parse as the hints.
3704                If an `Expression` instance is passed, it will be used as-is.
3705            dialect: The dialect used to parse the hints.
3706            copy: If `False`, modify this expression instance in-place.
3707
3708        Returns:
3709            The modified expression.
3710        """
3711        inst = maybe_copy(self, copy)
3712        inst.set(
3713            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3714        )
3715
3716        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]
3718    @property
3719    def named_selects(self) -> t.List[str]:
3720        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
3722    @property
3723    def is_star(self) -> bool:
3724        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3726    @property
3727    def selects(self) -> t.List[Expression]:
3728        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3734class Subquery(DerivedTable, Query):
3735    arg_types = {
3736        "this": True,
3737        "alias": False,
3738        "with": False,
3739        **QUERY_MODIFIERS,
3740    }
3741
3742    def unnest(self):
3743        """Returns the first non subquery."""
3744        expression = self
3745        while isinstance(expression, Subquery):
3746            expression = expression.this
3747        return expression
3748
3749    def unwrap(self) -> Subquery:
3750        expression = self
3751        while expression.same_parent and expression.is_wrapper:
3752            expression = t.cast(Subquery, expression.parent)
3753        return expression
3754
3755    def select(
3756        self,
3757        *expressions: t.Optional[ExpOrStr],
3758        append: bool = True,
3759        dialect: DialectType = None,
3760        copy: bool = True,
3761        **opts,
3762    ) -> Subquery:
3763        this = maybe_copy(self, copy)
3764        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3765        return this
3766
3767    @property
3768    def is_wrapper(self) -> bool:
3769        """
3770        Whether this Subquery acts as a simple wrapper around another expression.
3771
3772        SELECT * FROM (((SELECT * FROM t)))
3773                      ^
3774                      This corresponds to a "wrapper" Subquery node
3775        """
3776        return all(v is None for k, v in self.args.items() if k != "this")
3777
3778    @property
3779    def is_star(self) -> bool:
3780        return self.this.is_star
3781
3782    @property
3783    def output_name(self) -> str:
3784        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):
3742    def unnest(self):
3743        """Returns the first non subquery."""
3744        expression = self
3745        while isinstance(expression, Subquery):
3746            expression = expression.this
3747        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3749    def unwrap(self) -> Subquery:
3750        expression = self
3751        while expression.same_parent and expression.is_wrapper:
3752            expression = t.cast(Subquery, expression.parent)
3753        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
3755    def select(
3756        self,
3757        *expressions: t.Optional[ExpOrStr],
3758        append: bool = True,
3759        dialect: DialectType = None,
3760        copy: bool = True,
3761        **opts,
3762    ) -> Subquery:
3763        this = maybe_copy(self, copy)
3764        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3765        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
3767    @property
3768    def is_wrapper(self) -> bool:
3769        """
3770        Whether this Subquery acts as a simple wrapper around another expression.
3771
3772        SELECT * FROM (((SELECT * FROM t)))
3773                      ^
3774                      This corresponds to a "wrapper" Subquery node
3775        """
3776        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
3778    @property
3779    def is_star(self) -> bool:
3780        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3782    @property
3783    def output_name(self) -> str:
3784        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):
3787class TableSample(Expression):
3788    arg_types = {
3789        "this": False,
3790        "expressions": False,
3791        "method": False,
3792        "bucket_numerator": False,
3793        "bucket_denominator": False,
3794        "bucket_field": False,
3795        "percent": False,
3796        "rows": False,
3797        "size": False,
3798        "seed": False,
3799    }
arg_types = {'this': False, '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):
3802class Tag(Expression):
3803    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3804
3805    arg_types = {
3806        "this": False,
3807        "prefix": False,
3808        "postfix": False,
3809    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3814class Pivot(Expression):
3815    arg_types = {
3816        "this": False,
3817        "alias": False,
3818        "expressions": False,
3819        "field": False,
3820        "unpivot": False,
3821        "using": False,
3822        "group": False,
3823        "columns": False,
3824        "include_nulls": False,
3825    }
3826
3827    @property
3828    def unpivot(self) -> bool:
3829        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3827    @property
3828    def unpivot(self) -> bool:
3829        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3832class Window(Condition):
3833    arg_types = {
3834        "this": True,
3835        "partition_by": False,
3836        "order": False,
3837        "spec": False,
3838        "alias": False,
3839        "over": False,
3840        "first": False,
3841    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3844class WindowSpec(Expression):
3845    arg_types = {
3846        "kind": False,
3847        "start": False,
3848        "start_side": False,
3849        "end": False,
3850        "end_side": False,
3851    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3854class PreWhere(Expression):
3855    pass
key = 'prewhere'
class Where(Expression):
3858class Where(Expression):
3859    pass
key = 'where'
class Star(Expression):
3862class Star(Expression):
3863    arg_types = {"except": False, "replace": False, "rename": False}
3864
3865    @property
3866    def name(self) -> str:
3867        return "*"
3868
3869    @property
3870    def output_name(self) -> str:
3871        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3865    @property
3866    def name(self) -> str:
3867        return "*"
output_name: str
3869    @property
3870    def output_name(self) -> str:
3871        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):
3874class Parameter(Condition):
3875    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3878class SessionParameter(Condition):
3879    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3882class Placeholder(Condition):
3883    arg_types = {"this": False, "kind": False}
3884
3885    @property
3886    def name(self) -> str:
3887        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3885    @property
3886    def name(self) -> str:
3887        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3890class Null(Condition):
3891    arg_types: t.Dict[str, t.Any] = {}
3892
3893    @property
3894    def name(self) -> str:
3895        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3893    @property
3894    def name(self) -> str:
3895        return "NULL"
key = 'null'
class Boolean(Condition):
3898class Boolean(Condition):
3899    pass
key = 'boolean'
class DataTypeParam(Expression):
3902class DataTypeParam(Expression):
3903    arg_types = {"this": True, "expression": False}
3904
3905    @property
3906    def name(self) -> str:
3907        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3905    @property
3906    def name(self) -> str:
3907        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3910class DataType(Expression):
3911    arg_types = {
3912        "this": True,
3913        "expressions": False,
3914        "nested": False,
3915        "values": False,
3916        "prefix": False,
3917        "kind": False,
3918    }
3919
3920    class Type(AutoName):
3921        ARRAY = auto()
3922        AGGREGATEFUNCTION = auto()
3923        SIMPLEAGGREGATEFUNCTION = auto()
3924        BIGDECIMAL = auto()
3925        BIGINT = auto()
3926        BIGSERIAL = auto()
3927        BINARY = auto()
3928        BIT = auto()
3929        BOOLEAN = auto()
3930        BPCHAR = auto()
3931        CHAR = auto()
3932        DATE = auto()
3933        DATE32 = auto()
3934        DATEMULTIRANGE = auto()
3935        DATERANGE = auto()
3936        DATETIME = auto()
3937        DATETIME64 = auto()
3938        DECIMAL = auto()
3939        DOUBLE = auto()
3940        ENUM = auto()
3941        ENUM8 = auto()
3942        ENUM16 = auto()
3943        FIXEDSTRING = auto()
3944        FLOAT = auto()
3945        GEOGRAPHY = auto()
3946        GEOMETRY = auto()
3947        HLLSKETCH = auto()
3948        HSTORE = auto()
3949        IMAGE = auto()
3950        INET = auto()
3951        INT = auto()
3952        INT128 = auto()
3953        INT256 = auto()
3954        INT4MULTIRANGE = auto()
3955        INT4RANGE = auto()
3956        INT8MULTIRANGE = auto()
3957        INT8RANGE = auto()
3958        INTERVAL = auto()
3959        IPADDRESS = auto()
3960        IPPREFIX = auto()
3961        IPV4 = auto()
3962        IPV6 = auto()
3963        JSON = auto()
3964        JSONB = auto()
3965        LONGBLOB = auto()
3966        LONGTEXT = auto()
3967        LOWCARDINALITY = auto()
3968        MAP = auto()
3969        MEDIUMBLOB = auto()
3970        MEDIUMINT = auto()
3971        MEDIUMTEXT = auto()
3972        MONEY = auto()
3973        NAME = auto()
3974        NCHAR = auto()
3975        NESTED = auto()
3976        NULL = auto()
3977        NULLABLE = auto()
3978        NUMMULTIRANGE = auto()
3979        NUMRANGE = auto()
3980        NVARCHAR = auto()
3981        OBJECT = auto()
3982        ROWVERSION = auto()
3983        SERIAL = auto()
3984        SET = auto()
3985        SMALLINT = auto()
3986        SMALLMONEY = auto()
3987        SMALLSERIAL = auto()
3988        STRUCT = auto()
3989        SUPER = auto()
3990        TEXT = auto()
3991        TINYBLOB = auto()
3992        TINYTEXT = auto()
3993        TIME = auto()
3994        TIMETZ = auto()
3995        TIMESTAMP = auto()
3996        TIMESTAMPNTZ = auto()
3997        TIMESTAMPLTZ = auto()
3998        TIMESTAMPTZ = auto()
3999        TIMESTAMP_S = auto()
4000        TIMESTAMP_MS = auto()
4001        TIMESTAMP_NS = auto()
4002        TINYINT = auto()
4003        TSMULTIRANGE = auto()
4004        TSRANGE = auto()
4005        TSTZMULTIRANGE = auto()
4006        TSTZRANGE = auto()
4007        UBIGINT = auto()
4008        UINT = auto()
4009        UINT128 = auto()
4010        UINT256 = auto()
4011        UMEDIUMINT = auto()
4012        UDECIMAL = auto()
4013        UNIQUEIDENTIFIER = auto()
4014        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4015        USERDEFINED = "USER-DEFINED"
4016        USMALLINT = auto()
4017        UTINYINT = auto()
4018        UUID = auto()
4019        VARBINARY = auto()
4020        VARCHAR = auto()
4021        VARIANT = auto()
4022        XML = auto()
4023        YEAR = auto()
4024        TDIGEST = auto()
4025
4026    STRUCT_TYPES = {
4027        Type.NESTED,
4028        Type.OBJECT,
4029        Type.STRUCT,
4030    }
4031
4032    NESTED_TYPES = {
4033        *STRUCT_TYPES,
4034        Type.ARRAY,
4035        Type.MAP,
4036    }
4037
4038    TEXT_TYPES = {
4039        Type.CHAR,
4040        Type.NCHAR,
4041        Type.NVARCHAR,
4042        Type.TEXT,
4043        Type.VARCHAR,
4044        Type.NAME,
4045    }
4046
4047    SIGNED_INTEGER_TYPES = {
4048        Type.BIGINT,
4049        Type.INT,
4050        Type.INT128,
4051        Type.INT256,
4052        Type.MEDIUMINT,
4053        Type.SMALLINT,
4054        Type.TINYINT,
4055    }
4056
4057    UNSIGNED_INTEGER_TYPES = {
4058        Type.UBIGINT,
4059        Type.UINT,
4060        Type.UINT128,
4061        Type.UINT256,
4062        Type.UMEDIUMINT,
4063        Type.USMALLINT,
4064        Type.UTINYINT,
4065    }
4066
4067    INTEGER_TYPES = {
4068        *SIGNED_INTEGER_TYPES,
4069        *UNSIGNED_INTEGER_TYPES,
4070        Type.BIT,
4071    }
4072
4073    FLOAT_TYPES = {
4074        Type.DOUBLE,
4075        Type.FLOAT,
4076    }
4077
4078    REAL_TYPES = {
4079        *FLOAT_TYPES,
4080        Type.BIGDECIMAL,
4081        Type.DECIMAL,
4082        Type.MONEY,
4083        Type.SMALLMONEY,
4084        Type.UDECIMAL,
4085    }
4086
4087    NUMERIC_TYPES = {
4088        *INTEGER_TYPES,
4089        *REAL_TYPES,
4090    }
4091
4092    TEMPORAL_TYPES = {
4093        Type.DATE,
4094        Type.DATE32,
4095        Type.DATETIME,
4096        Type.DATETIME64,
4097        Type.TIME,
4098        Type.TIMESTAMP,
4099        Type.TIMESTAMPNTZ,
4100        Type.TIMESTAMPLTZ,
4101        Type.TIMESTAMPTZ,
4102        Type.TIMESTAMP_MS,
4103        Type.TIMESTAMP_NS,
4104        Type.TIMESTAMP_S,
4105        Type.TIMETZ,
4106    }
4107
4108    @classmethod
4109    def build(
4110        cls,
4111        dtype: DATA_TYPE,
4112        dialect: DialectType = None,
4113        udt: bool = False,
4114        copy: bool = True,
4115        **kwargs,
4116    ) -> DataType:
4117        """
4118        Constructs a DataType object.
4119
4120        Args:
4121            dtype: the data type of interest.
4122            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4123            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4124                DataType, thus creating a user-defined type.
4125            copy: whether to copy the data type.
4126            kwargs: additional arguments to pass in the constructor of DataType.
4127
4128        Returns:
4129            The constructed DataType object.
4130        """
4131        from sqlglot import parse_one
4132
4133        if isinstance(dtype, str):
4134            if dtype.upper() == "UNKNOWN":
4135                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4136
4137            try:
4138                data_type_exp = parse_one(
4139                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4140                )
4141            except ParseError:
4142                if udt:
4143                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4144                raise
4145        elif isinstance(dtype, DataType.Type):
4146            data_type_exp = DataType(this=dtype)
4147        elif isinstance(dtype, DataType):
4148            return maybe_copy(dtype, copy)
4149        else:
4150            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4151
4152        return DataType(**{**data_type_exp.args, **kwargs})
4153
4154    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4155        """
4156        Checks whether this DataType matches one of the provided data types. Nested types or precision
4157        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4158
4159        Args:
4160            dtypes: the data types to compare this DataType to.
4161
4162        Returns:
4163            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4164        """
4165        for dtype in dtypes:
4166            other = DataType.build(dtype, copy=False, udt=True)
4167
4168            if (
4169                other.expressions
4170                or self.this == DataType.Type.USERDEFINED
4171                or other.this == DataType.Type.USERDEFINED
4172            ):
4173                matches = self == other
4174            else:
4175                matches = self.this == other.this
4176
4177            if matches:
4178                return True
4179        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>}
NESTED_TYPES = {<Type.NESTED: 'NESTED'>, <Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.ARRAY: 'ARRAY'>, <Type.STRUCT: 'STRUCT'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>}
SIGNED_INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>}
INTEGER_TYPES = {<Type.UINT128: 'UINT128'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.UDECIMAL: 'UDECIMAL'>}
NUMERIC_TYPES = {<Type.UINT256: 'UINT256'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.MONEY: 'MONEY'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UBIGINT: 'UBIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.FLOAT: 'FLOAT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4108    @classmethod
4109    def build(
4110        cls,
4111        dtype: DATA_TYPE,
4112        dialect: DialectType = None,
4113        udt: bool = False,
4114        copy: bool = True,
4115        **kwargs,
4116    ) -> DataType:
4117        """
4118        Constructs a DataType object.
4119
4120        Args:
4121            dtype: the data type of interest.
4122            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4123            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4124                DataType, thus creating a user-defined type.
4125            copy: whether to copy the data type.
4126            kwargs: additional arguments to pass in the constructor of DataType.
4127
4128        Returns:
4129            The constructed DataType object.
4130        """
4131        from sqlglot import parse_one
4132
4133        if isinstance(dtype, str):
4134            if dtype.upper() == "UNKNOWN":
4135                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4136
4137            try:
4138                data_type_exp = parse_one(
4139                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4140                )
4141            except ParseError:
4142                if udt:
4143                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4144                raise
4145        elif isinstance(dtype, DataType.Type):
4146            data_type_exp = DataType(this=dtype)
4147        elif isinstance(dtype, DataType):
4148            return maybe_copy(dtype, copy)
4149        else:
4150            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4151
4152        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4154    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4155        """
4156        Checks whether this DataType matches one of the provided data types. Nested types or precision
4157        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4158
4159        Args:
4160            dtypes: the data types to compare this DataType to.
4161
4162        Returns:
4163            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4164        """
4165        for dtype in dtypes:
4166            other = DataType.build(dtype, copy=False, udt=True)
4167
4168            if (
4169                other.expressions
4170                or self.this == DataType.Type.USERDEFINED
4171                or other.this == DataType.Type.USERDEFINED
4172            ):
4173                matches = self == other
4174            else:
4175                matches = self.this == other.this
4176
4177            if matches:
4178                return True
4179        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.
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):
3920    class Type(AutoName):
3921        ARRAY = auto()
3922        AGGREGATEFUNCTION = auto()
3923        SIMPLEAGGREGATEFUNCTION = auto()
3924        BIGDECIMAL = auto()
3925        BIGINT = auto()
3926        BIGSERIAL = auto()
3927        BINARY = auto()
3928        BIT = auto()
3929        BOOLEAN = auto()
3930        BPCHAR = auto()
3931        CHAR = auto()
3932        DATE = auto()
3933        DATE32 = auto()
3934        DATEMULTIRANGE = auto()
3935        DATERANGE = auto()
3936        DATETIME = auto()
3937        DATETIME64 = auto()
3938        DECIMAL = auto()
3939        DOUBLE = auto()
3940        ENUM = auto()
3941        ENUM8 = auto()
3942        ENUM16 = auto()
3943        FIXEDSTRING = auto()
3944        FLOAT = auto()
3945        GEOGRAPHY = auto()
3946        GEOMETRY = auto()
3947        HLLSKETCH = auto()
3948        HSTORE = auto()
3949        IMAGE = auto()
3950        INET = auto()
3951        INT = auto()
3952        INT128 = auto()
3953        INT256 = auto()
3954        INT4MULTIRANGE = auto()
3955        INT4RANGE = auto()
3956        INT8MULTIRANGE = auto()
3957        INT8RANGE = auto()
3958        INTERVAL = auto()
3959        IPADDRESS = auto()
3960        IPPREFIX = auto()
3961        IPV4 = auto()
3962        IPV6 = auto()
3963        JSON = auto()
3964        JSONB = auto()
3965        LONGBLOB = auto()
3966        LONGTEXT = auto()
3967        LOWCARDINALITY = auto()
3968        MAP = auto()
3969        MEDIUMBLOB = auto()
3970        MEDIUMINT = auto()
3971        MEDIUMTEXT = auto()
3972        MONEY = auto()
3973        NAME = auto()
3974        NCHAR = auto()
3975        NESTED = auto()
3976        NULL = auto()
3977        NULLABLE = auto()
3978        NUMMULTIRANGE = auto()
3979        NUMRANGE = auto()
3980        NVARCHAR = auto()
3981        OBJECT = auto()
3982        ROWVERSION = auto()
3983        SERIAL = auto()
3984        SET = auto()
3985        SMALLINT = auto()
3986        SMALLMONEY = auto()
3987        SMALLSERIAL = auto()
3988        STRUCT = auto()
3989        SUPER = auto()
3990        TEXT = auto()
3991        TINYBLOB = auto()
3992        TINYTEXT = auto()
3993        TIME = auto()
3994        TIMETZ = auto()
3995        TIMESTAMP = auto()
3996        TIMESTAMPNTZ = auto()
3997        TIMESTAMPLTZ = auto()
3998        TIMESTAMPTZ = auto()
3999        TIMESTAMP_S = auto()
4000        TIMESTAMP_MS = auto()
4001        TIMESTAMP_NS = auto()
4002        TINYINT = auto()
4003        TSMULTIRANGE = auto()
4004        TSRANGE = auto()
4005        TSTZMULTIRANGE = auto()
4006        TSTZRANGE = auto()
4007        UBIGINT = auto()
4008        UINT = auto()
4009        UINT128 = auto()
4010        UINT256 = auto()
4011        UMEDIUMINT = auto()
4012        UDECIMAL = auto()
4013        UNIQUEIDENTIFIER = auto()
4014        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4015        USERDEFINED = "USER-DEFINED"
4016        USMALLINT = auto()
4017        UTINYINT = auto()
4018        UUID = auto()
4019        VARBINARY = auto()
4020        VARCHAR = auto()
4021        VARIANT = auto()
4022        XML = auto()
4023        YEAR = auto()
4024        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'>
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'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
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'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
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'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
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'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4186class PseudoType(DataType):
4187    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4191class ObjectIdentifier(DataType):
4192    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4196class SubqueryPredicate(Predicate):
4197    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4200class All(SubqueryPredicate):
4201    pass
key = 'all'
class Any(SubqueryPredicate):
4204class Any(SubqueryPredicate):
4205    pass
key = 'any'
class Exists(SubqueryPredicate):
4208class Exists(SubqueryPredicate):
4209    pass
key = 'exists'
class Command(Expression):
4214class Command(Expression):
4215    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4218class Transaction(Expression):
4219    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4222class Commit(Expression):
4223    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4226class Rollback(Expression):
4227    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4230class AlterTable(Expression):
4231    arg_types = {
4232        "this": True,
4233        "actions": True,
4234        "exists": False,
4235        "only": False,
4236        "options": False,
4237        "cluster": False,
4238    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4241class AddConstraint(Expression):
4242    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4245class DropPartition(Expression):
4246    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4250class ReplacePartition(Expression):
4251    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4255class Binary(Condition):
4256    arg_types = {"this": True, "expression": True}
4257
4258    @property
4259    def left(self) -> Expression:
4260        return self.this
4261
4262    @property
4263    def right(self) -> Expression:
4264        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4258    @property
4259    def left(self) -> Expression:
4260        return self.this
right: Expression
4262    @property
4263    def right(self) -> Expression:
4264        return self.expression
key = 'binary'
class Add(Binary):
4267class Add(Binary):
4268    pass
key = 'add'
class Connector(Binary):
4271class Connector(Binary):
4272    pass
key = 'connector'
class And(Connector):
4275class And(Connector):
4276    pass
key = 'and'
class Or(Connector):
4279class Or(Connector):
4280    pass
key = 'or'
class BitwiseAnd(Binary):
4283class BitwiseAnd(Binary):
4284    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4287class BitwiseLeftShift(Binary):
4288    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4291class BitwiseOr(Binary):
4292    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4295class BitwiseRightShift(Binary):
4296    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4299class BitwiseXor(Binary):
4300    pass
key = 'bitwisexor'
class Div(Binary):
4303class Div(Binary):
4304    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):
4307class Overlaps(Binary):
4308    pass
key = 'overlaps'
class Dot(Binary):
4311class Dot(Binary):
4312    @property
4313    def is_star(self) -> bool:
4314        return self.expression.is_star
4315
4316    @property
4317    def name(self) -> str:
4318        return self.expression.name
4319
4320    @property
4321    def output_name(self) -> str:
4322        return self.name
4323
4324    @classmethod
4325    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4326        """Build a Dot object with a sequence of expressions."""
4327        if len(expressions) < 2:
4328            raise ValueError("Dot requires >= 2 expressions.")
4329
4330        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4331
4332    @property
4333    def parts(self) -> t.List[Expression]:
4334        """Return the parts of a table / column in order catalog, db, table."""
4335        this, *parts = self.flatten()
4336
4337        parts.reverse()
4338
4339        for arg in COLUMN_PARTS:
4340            part = this.args.get(arg)
4341
4342            if isinstance(part, Expression):
4343                parts.append(part)
4344
4345        parts.reverse()
4346        return parts
is_star: bool
4312    @property
4313    def is_star(self) -> bool:
4314        return self.expression.is_star

Checks whether an expression is a star.

name: str
4316    @property
4317    def name(self) -> str:
4318        return self.expression.name
output_name: str
4320    @property
4321    def output_name(self) -> str:
4322        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:
4324    @classmethod
4325    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4326        """Build a Dot object with a sequence of expressions."""
4327        if len(expressions) < 2:
4328            raise ValueError("Dot requires >= 2 expressions.")
4329
4330        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]
4332    @property
4333    def parts(self) -> t.List[Expression]:
4334        """Return the parts of a table / column in order catalog, db, table."""
4335        this, *parts = self.flatten()
4336
4337        parts.reverse()
4338
4339        for arg in COLUMN_PARTS:
4340            part = this.args.get(arg)
4341
4342            if isinstance(part, Expression):
4343                parts.append(part)
4344
4345        parts.reverse()
4346        return parts

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

key = 'dot'
class DPipe(Binary):
4349class DPipe(Binary):
4350    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4353class EQ(Binary, Predicate):
4354    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4357class NullSafeEQ(Binary, Predicate):
4358    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4361class NullSafeNEQ(Binary, Predicate):
4362    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4366class PropertyEQ(Binary):
4367    pass
key = 'propertyeq'
class Distance(Binary):
4370class Distance(Binary):
4371    pass
key = 'distance'
class Escape(Binary):
4374class Escape(Binary):
4375    pass
key = 'escape'
class Glob(Binary, Predicate):
4378class Glob(Binary, Predicate):
4379    pass
key = 'glob'
class GT(Binary, Predicate):
4382class GT(Binary, Predicate):
4383    pass
key = 'gt'
class GTE(Binary, Predicate):
4386class GTE(Binary, Predicate):
4387    pass
key = 'gte'
class ILike(Binary, Predicate):
4390class ILike(Binary, Predicate):
4391    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4394class ILikeAny(Binary, Predicate):
4395    pass
key = 'ilikeany'
class IntDiv(Binary):
4398class IntDiv(Binary):
4399    pass
key = 'intdiv'
class Is(Binary, Predicate):
4402class Is(Binary, Predicate):
4403    pass
key = 'is'
class Kwarg(Binary):
4406class Kwarg(Binary):
4407    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4410class Like(Binary, Predicate):
4411    pass
key = 'like'
class LikeAny(Binary, Predicate):
4414class LikeAny(Binary, Predicate):
4415    pass
key = 'likeany'
class LT(Binary, Predicate):
4418class LT(Binary, Predicate):
4419    pass
key = 'lt'
class LTE(Binary, Predicate):
4422class LTE(Binary, Predicate):
4423    pass
key = 'lte'
class Mod(Binary):
4426class Mod(Binary):
4427    pass
key = 'mod'
class Mul(Binary):
4430class Mul(Binary):
4431    pass
key = 'mul'
class NEQ(Binary, Predicate):
4434class NEQ(Binary, Predicate):
4435    pass
key = 'neq'
class Operator(Binary):
4439class Operator(Binary):
4440    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4443class SimilarTo(Binary, Predicate):
4444    pass
key = 'similarto'
class Slice(Binary):
4447class Slice(Binary):
4448    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4451class Sub(Binary):
4452    pass
key = 'sub'
class Unary(Condition):
4457class Unary(Condition):
4458    pass
key = 'unary'
class BitwiseNot(Unary):
4461class BitwiseNot(Unary):
4462    pass
key = 'bitwisenot'
class Not(Unary):
4465class Not(Unary):
4466    pass
key = 'not'
class Paren(Unary):
4469class Paren(Unary):
4470    @property
4471    def output_name(self) -> str:
4472        return self.this.name
output_name: str
4470    @property
4471    def output_name(self) -> str:
4472        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):
4475class Neg(Unary):
4476    pass
key = 'neg'
class Alias(Expression):
4479class Alias(Expression):
4480    arg_types = {"this": True, "alias": False}
4481
4482    @property
4483    def output_name(self) -> str:
4484        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4482    @property
4483    def output_name(self) -> str:
4484        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):
4489class PivotAlias(Alias):
4490    pass
key = 'pivotalias'
class Aliases(Expression):
4493class Aliases(Expression):
4494    arg_types = {"this": True, "expressions": True}
4495
4496    @property
4497    def aliases(self):
4498        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4496    @property
4497    def aliases(self):
4498        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4502class AtIndex(Expression):
4503    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4506class AtTimeZone(Expression):
4507    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4510class FromTimeZone(Expression):
4511    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4514class Between(Predicate):
4515    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4518class Bracket(Condition):
4519    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4520    arg_types = {
4521        "this": True,
4522        "expressions": True,
4523        "offset": False,
4524        "safe": False,
4525        "returns_list_for_maps": False,
4526    }
4527
4528    @property
4529    def output_name(self) -> str:
4530        if len(self.expressions) == 1:
4531            return self.expressions[0].output_name
4532
4533        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4528    @property
4529    def output_name(self) -> str:
4530        if len(self.expressions) == 1:
4531            return self.expressions[0].output_name
4532
4533        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):
4536class Distinct(Expression):
4537    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4540class In(Predicate):
4541    arg_types = {
4542        "this": True,
4543        "expressions": False,
4544        "query": False,
4545        "unnest": False,
4546        "field": False,
4547        "is_global": False,
4548    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4552class ForIn(Expression):
4553    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4556class TimeUnit(Expression):
4557    """Automatically converts unit arg into a var."""
4558
4559    arg_types = {"unit": False}
4560
4561    UNABBREVIATED_UNIT_NAME = {
4562        "D": "DAY",
4563        "H": "HOUR",
4564        "M": "MINUTE",
4565        "MS": "MILLISECOND",
4566        "NS": "NANOSECOND",
4567        "Q": "QUARTER",
4568        "S": "SECOND",
4569        "US": "MICROSECOND",
4570        "W": "WEEK",
4571        "Y": "YEAR",
4572    }
4573
4574    VAR_LIKE = (Column, Literal, Var)
4575
4576    def __init__(self, **args):
4577        unit = args.get("unit")
4578        if isinstance(unit, self.VAR_LIKE):
4579            args["unit"] = Var(
4580                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4581            )
4582        elif isinstance(unit, Week):
4583            unit.set("this", Var(this=unit.this.name.upper()))
4584
4585        super().__init__(**args)
4586
4587    @property
4588    def unit(self) -> t.Optional[Var | IntervalSpan]:
4589        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4576    def __init__(self, **args):
4577        unit = args.get("unit")
4578        if isinstance(unit, self.VAR_LIKE):
4579            args["unit"] = Var(
4580                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4581            )
4582        elif isinstance(unit, Week):
4583            unit.set("this", Var(this=unit.this.name.upper()))
4584
4585        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]
4587    @property
4588    def unit(self) -> t.Optional[Var | IntervalSpan]:
4589        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4592class IntervalOp(TimeUnit):
4593    arg_types = {"unit": True, "expression": True}
4594
4595    def interval(self):
4596        return Interval(
4597            this=self.expression.copy(),
4598            unit=self.unit.copy(),
4599        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4595    def interval(self):
4596        return Interval(
4597            this=self.expression.copy(),
4598            unit=self.unit.copy(),
4599        )
key = 'intervalop'
class IntervalSpan(DataType):
4605class IntervalSpan(DataType):
4606    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4609class Interval(TimeUnit):
4610    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4613class IgnoreNulls(Expression):
4614    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4617class RespectNulls(Expression):
4618    pass
key = 'respectnulls'
class HavingMax(Expression):
4622class HavingMax(Expression):
4623    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4627class Func(Condition):
4628    """
4629    The base class for all function expressions.
4630
4631    Attributes:
4632        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4633            treated as a variable length argument and the argument's value will be stored as a list.
4634        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4635            function expression. These values are used to map this node to a name during parsing as
4636            well as to provide the function's name during SQL string generation. By default the SQL
4637            name is set to the expression's class name transformed to snake case.
4638    """
4639
4640    is_var_len_args = False
4641
4642    @classmethod
4643    def from_arg_list(cls, args):
4644        if cls.is_var_len_args:
4645            all_arg_keys = list(cls.arg_types)
4646            # If this function supports variable length argument treat the last argument as such.
4647            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4648            num_non_var = len(non_var_len_arg_keys)
4649
4650            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4651            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4652        else:
4653            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4654
4655        return cls(**args_dict)
4656
4657    @classmethod
4658    def sql_names(cls):
4659        if cls is Func:
4660            raise NotImplementedError(
4661                "SQL name is only supported by concrete function implementations"
4662            )
4663        if "_sql_names" not in cls.__dict__:
4664            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4665        return cls._sql_names
4666
4667    @classmethod
4668    def sql_name(cls):
4669        return cls.sql_names()[0]
4670
4671    @classmethod
4672    def default_parser_mappings(cls):
4673        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):
4642    @classmethod
4643    def from_arg_list(cls, args):
4644        if cls.is_var_len_args:
4645            all_arg_keys = list(cls.arg_types)
4646            # If this function supports variable length argument treat the last argument as such.
4647            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4648            num_non_var = len(non_var_len_arg_keys)
4649
4650            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4651            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4652        else:
4653            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4654
4655        return cls(**args_dict)
@classmethod
def sql_names(cls):
4657    @classmethod
4658    def sql_names(cls):
4659        if cls is Func:
4660            raise NotImplementedError(
4661                "SQL name is only supported by concrete function implementations"
4662            )
4663        if "_sql_names" not in cls.__dict__:
4664            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4665        return cls._sql_names
@classmethod
def sql_name(cls):
4667    @classmethod
4668    def sql_name(cls):
4669        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4671    @classmethod
4672    def default_parser_mappings(cls):
4673        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4676class AggFunc(Func):
4677    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4680class ParameterizedAgg(AggFunc):
4681    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4684class Abs(Func):
4685    pass
key = 'abs'
class ArgMax(AggFunc):
4688class ArgMax(AggFunc):
4689    arg_types = {"this": True, "expression": True, "count": False}
4690    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4693class ArgMin(AggFunc):
4694    arg_types = {"this": True, "expression": True, "count": False}
4695    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4698class ApproxTopK(AggFunc):
4699    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4702class Flatten(Func):
4703    pass
key = 'flatten'
class Transform(Func):
4707class Transform(Func):
4708    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4711class Anonymous(Func):
4712    arg_types = {"this": True, "expressions": False}
4713    is_var_len_args = True
4714
4715    @property
4716    def name(self) -> str:
4717        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
4715    @property
4716    def name(self) -> str:
4717        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4720class AnonymousAggFunc(AggFunc):
4721    arg_types = {"this": True, "expressions": False}
4722    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4726class CombinedAggFunc(AnonymousAggFunc):
4727    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4730class CombinedParameterizedAgg(ParameterizedAgg):
4731    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
4736class Hll(AggFunc):
4737    arg_types = {"this": True, "expressions": False}
4738    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4741class ApproxDistinct(AggFunc):
4742    arg_types = {"this": True, "accuracy": False}
4743    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4746class Array(Func):
4747    arg_types = {"expressions": False}
4748    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4752class ToArray(Func):
4753    pass
key = 'toarray'
class ToChar(Func):
4758class ToChar(Func):
4759    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4764class ToNumber(Func):
4765    arg_types = {
4766        "this": True,
4767        "format": False,
4768        "nlsparam": False,
4769        "precision": False,
4770        "scale": False,
4771    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4775class Convert(Func):
4776    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4779class GenerateSeries(Func):
4780    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 ArrayAgg(AggFunc):
4783class ArrayAgg(AggFunc):
4784    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4787class ArrayUniqueAgg(AggFunc):
4788    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4791class ArrayAll(Func):
4792    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4796class ArrayAny(Func):
4797    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4800class ArrayConcat(Func):
4801    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4802    arg_types = {"this": True, "expressions": False}
4803    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4806class ArrayConstructCompact(Func):
4807    arg_types = {"expressions": True}
4808    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4811class ArrayContains(Binary, Func):
4812    pass
key = 'arraycontains'
class ArrayContained(Binary):
4815class ArrayContained(Binary):
4816    pass
key = 'arraycontained'
class ArrayFilter(Func):
4819class ArrayFilter(Func):
4820    arg_types = {"this": True, "expression": True}
4821    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4824class ArrayToString(Func):
4825    arg_types = {"this": True, "expression": True, "null": False}
4826    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4829class ArrayOverlaps(Binary, Func):
4830    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4833class ArraySize(Func):
4834    arg_types = {"this": True, "expression": False}
4835    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4838class ArraySort(Func):
4839    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4842class ArraySum(Func):
4843    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4846class ArrayUnionAgg(AggFunc):
4847    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4850class Avg(AggFunc):
4851    pass
key = 'avg'
class AnyValue(AggFunc):
4854class AnyValue(AggFunc):
4855    pass
key = 'anyvalue'
class Lag(AggFunc):
4858class Lag(AggFunc):
4859    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4862class Lead(AggFunc):
4863    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4868class First(AggFunc):
4869    pass
key = 'first'
class Last(AggFunc):
4872class Last(AggFunc):
4873    pass
key = 'last'
class FirstValue(AggFunc):
4876class FirstValue(AggFunc):
4877    pass
key = 'firstvalue'
class LastValue(AggFunc):
4880class LastValue(AggFunc):
4881    pass
key = 'lastvalue'
class NthValue(AggFunc):
4884class NthValue(AggFunc):
4885    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4888class Case(Func):
4889    arg_types = {"this": False, "ifs": True, "default": False}
4890
4891    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4892        instance = maybe_copy(self, copy)
4893        instance.append(
4894            "ifs",
4895            If(
4896                this=maybe_parse(condition, copy=copy, **opts),
4897                true=maybe_parse(then, copy=copy, **opts),
4898            ),
4899        )
4900        return instance
4901
4902    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4903        instance = maybe_copy(self, copy)
4904        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4905        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:
4891    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4892        instance = maybe_copy(self, copy)
4893        instance.append(
4894            "ifs",
4895            If(
4896                this=maybe_parse(condition, copy=copy, **opts),
4897                true=maybe_parse(then, copy=copy, **opts),
4898            ),
4899        )
4900        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4902    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4903        instance = maybe_copy(self, copy)
4904        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4905        return instance
key = 'case'
class Cast(Func):
4908class Cast(Func):
4909    arg_types = {
4910        "this": True,
4911        "to": True,
4912        "format": False,
4913        "safe": False,
4914        "action": False,
4915    }
4916
4917    @property
4918    def name(self) -> str:
4919        return self.this.name
4920
4921    @property
4922    def to(self) -> DataType:
4923        return self.args["to"]
4924
4925    @property
4926    def output_name(self) -> str:
4927        return self.name
4928
4929    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4930        """
4931        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4932        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4933        array<int> != array<float>.
4934
4935        Args:
4936            dtypes: the data types to compare this Cast's DataType to.
4937
4938        Returns:
4939            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4940        """
4941        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4917    @property
4918    def name(self) -> str:
4919        return self.this.name
to: DataType
4921    @property
4922    def to(self) -> DataType:
4923        return self.args["to"]
output_name: str
4925    @property
4926    def output_name(self) -> str:
4927        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4929    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4930        """
4931        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4932        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4933        array<int> != array<float>.
4934
4935        Args:
4936            dtypes: the data types to compare this Cast's DataType to.
4937
4938        Returns:
4939            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4940        """
4941        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):
4944class TryCast(Cast):
4945    pass
key = 'trycast'
class Try(Func):
4948class Try(Func):
4949    pass
key = 'try'
class CastToStrType(Func):
4952class CastToStrType(Func):
4953    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4956class Collate(Binary, Func):
4957    pass
key = 'collate'
class Ceil(Func):
4960class Ceil(Func):
4961    arg_types = {"this": True, "decimals": False}
4962    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4965class Coalesce(Func):
4966    arg_types = {"this": True, "expressions": False}
4967    is_var_len_args = True
4968    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4971class Chr(Func):
4972    arg_types = {"this": True, "charset": False, "expressions": False}
4973    is_var_len_args = True
4974    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4977class Concat(Func):
4978    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4979    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4982class ConcatWs(Concat):
4983    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4987class ConnectByRoot(Func):
4988    pass
key = 'connectbyroot'
class Count(AggFunc):
4991class Count(AggFunc):
4992    arg_types = {"this": False, "expressions": False}
4993    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4996class CountIf(AggFunc):
4997    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5001class Cbrt(Func):
5002    pass
key = 'cbrt'
class CurrentDate(Func):
5005class CurrentDate(Func):
5006    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5009class CurrentDatetime(Func):
5010    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5013class CurrentTime(Func):
5014    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5017class CurrentTimestamp(Func):
5018    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5021class CurrentUser(Func):
5022    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5025class DateAdd(Func, IntervalOp):
5026    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5029class DateSub(Func, IntervalOp):
5030    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5033class DateDiff(Func, TimeUnit):
5034    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5035    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5038class DateTrunc(Func):
5039    arg_types = {"unit": True, "this": True, "zone": False}
5040
5041    def __init__(self, **args):
5042        unit = args.get("unit")
5043        if isinstance(unit, TimeUnit.VAR_LIKE):
5044            args["unit"] = Literal.string(
5045                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5046            )
5047        elif isinstance(unit, Week):
5048            unit.set("this", Literal.string(unit.this.name.upper()))
5049
5050        super().__init__(**args)
5051
5052    @property
5053    def unit(self) -> Expression:
5054        return self.args["unit"]
DateTrunc(**args)
5041    def __init__(self, **args):
5042        unit = args.get("unit")
5043        if isinstance(unit, TimeUnit.VAR_LIKE):
5044            args["unit"] = Literal.string(
5045                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5046            )
5047        elif isinstance(unit, Week):
5048            unit.set("this", Literal.string(unit.this.name.upper()))
5049
5050        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5052    @property
5053    def unit(self) -> Expression:
5054        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
5057class DatetimeAdd(Func, IntervalOp):
5058    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5061class DatetimeSub(Func, IntervalOp):
5062    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5065class DatetimeDiff(Func, TimeUnit):
5066    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5069class DatetimeTrunc(Func, TimeUnit):
5070    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5073class DayOfWeek(Func):
5074    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5077class DayOfMonth(Func):
5078    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5081class DayOfYear(Func):
5082    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5085class ToDays(Func):
5086    pass
key = 'todays'
class WeekOfYear(Func):
5089class WeekOfYear(Func):
5090    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5093class MonthsBetween(Func):
5094    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5097class LastDay(Func, TimeUnit):
5098    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5099    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5102class Extract(Func):
5103    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5106class Timestamp(Func):
5107    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5110class TimestampAdd(Func, TimeUnit):
5111    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5114class TimestampSub(Func, TimeUnit):
5115    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5118class TimestampDiff(Func, TimeUnit):
5119    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5120    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5123class TimestampTrunc(Func, TimeUnit):
5124    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5127class TimeAdd(Func, TimeUnit):
5128    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5131class TimeSub(Func, TimeUnit):
5132    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5135class TimeDiff(Func, TimeUnit):
5136    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5139class TimeTrunc(Func, TimeUnit):
5140    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5143class DateFromParts(Func):
5144    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5145    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5148class TimeFromParts(Func):
5149    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5150    arg_types = {
5151        "hour": True,
5152        "min": True,
5153        "sec": True,
5154        "nano": False,
5155        "fractions": False,
5156        "precision": False,
5157    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5160class DateStrToDate(Func):
5161    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5164class DateToDateStr(Func):
5165    pass
key = 'datetodatestr'
class DateToDi(Func):
5168class DateToDi(Func):
5169    pass
key = 'datetodi'
class Date(Func):
5173class Date(Func):
5174    arg_types = {"this": False, "zone": False, "expressions": False}
5175    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5178class Day(Func):
5179    pass
key = 'day'
class Decode(Func):
5182class Decode(Func):
5183    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5186class DiToDate(Func):
5187    pass
key = 'ditodate'
class Encode(Func):
5190class Encode(Func):
5191    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5194class Exp(Func):
5195    pass
key = 'exp'
class Explode(Func):
5199class Explode(Func):
5200    arg_types = {"this": True, "expressions": False}
5201    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5204class ExplodeOuter(Explode):
5205    pass
key = 'explodeouter'
class Posexplode(Explode):
5208class Posexplode(Explode):
5209    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5212class PosexplodeOuter(Posexplode, ExplodeOuter):
5213    pass
key = 'posexplodeouter'
class Floor(Func):
5216class Floor(Func):
5217    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5220class FromBase64(Func):
5221    pass
key = 'frombase64'
class ToBase64(Func):
5224class ToBase64(Func):
5225    pass
key = 'tobase64'
class GenerateDateArray(Func):
5228class GenerateDateArray(Func):
5229    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5232class Greatest(Func):
5233    arg_types = {"this": True, "expressions": False}
5234    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5237class GroupConcat(AggFunc):
5238    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5241class Hex(Func):
5242    pass
key = 'hex'
class LowerHex(Hex):
5245class LowerHex(Hex):
5246    pass
key = 'lowerhex'
class Xor(Connector, Func):
5249class Xor(Connector, Func):
5250    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5253class If(Func):
5254    arg_types = {"this": True, "true": True, "false": False}
5255    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5258class Nullif(Func):
5259    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5262class Initcap(Func):
5263    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5266class IsNan(Func):
5267    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5270class IsInf(Func):
5271    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5274class JSONPath(Expression):
5275    arg_types = {"expressions": True}
5276
5277    @property
5278    def output_name(self) -> str:
5279        last_segment = self.expressions[-1].this
5280        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5277    @property
5278    def output_name(self) -> str:
5279        last_segment = self.expressions[-1].this
5280        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):
5283class JSONPathPart(Expression):
5284    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5287class JSONPathFilter(JSONPathPart):
5288    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5291class JSONPathKey(JSONPathPart):
5292    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5295class JSONPathRecursive(JSONPathPart):
5296    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5299class JSONPathRoot(JSONPathPart):
5300    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5303class JSONPathScript(JSONPathPart):
5304    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5307class JSONPathSlice(JSONPathPart):
5308    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5311class JSONPathSelector(JSONPathPart):
5312    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5315class JSONPathSubscript(JSONPathPart):
5316    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5319class JSONPathUnion(JSONPathPart):
5320    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5323class JSONPathWildcard(JSONPathPart):
5324    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5327class FormatJson(Expression):
5328    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5331class JSONKeyValue(Expression):
5332    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5335class JSONObject(Func):
5336    arg_types = {
5337        "expressions": False,
5338        "null_handling": False,
5339        "unique_keys": False,
5340        "return_type": False,
5341        "encoding": False,
5342    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5345class JSONObjectAgg(AggFunc):
5346    arg_types = {
5347        "expressions": False,
5348        "null_handling": False,
5349        "unique_keys": False,
5350        "return_type": False,
5351        "encoding": False,
5352    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5356class JSONArray(Func):
5357    arg_types = {
5358        "expressions": True,
5359        "null_handling": False,
5360        "return_type": False,
5361        "strict": False,
5362    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5366class JSONArrayAgg(Func):
5367    arg_types = {
5368        "this": True,
5369        "order": False,
5370        "null_handling": False,
5371        "return_type": False,
5372        "strict": False,
5373    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5378class JSONColumnDef(Expression):
5379    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):
5382class JSONSchema(Expression):
5383    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5387class JSONTable(Func):
5388    arg_types = {
5389        "this": True,
5390        "schema": True,
5391        "path": False,
5392        "error_handling": False,
5393        "empty_handling": False,
5394    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5397class OpenJSONColumnDef(Expression):
5398    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):
5401class OpenJSON(Func):
5402    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5405class JSONBContains(Binary):
5406    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5409class JSONExtract(Binary, Func):
5410    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5411    _sql_names = ["JSON_EXTRACT"]
5412    is_var_len_args = True
5413
5414    @property
5415    def output_name(self) -> str:
5416        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5414    @property
5415    def output_name(self) -> str:
5416        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 JSONExtractScalar(Binary, Func):
5419class JSONExtractScalar(Binary, Func):
5420    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5421    _sql_names = ["JSON_EXTRACT_SCALAR"]
5422    is_var_len_args = True
5423
5424    @property
5425    def output_name(self) -> str:
5426        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5424    @property
5425    def output_name(self) -> str:
5426        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):
5429class JSONBExtract(Binary, Func):
5430    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5433class JSONBExtractScalar(Binary, Func):
5434    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5437class JSONFormat(Func):
5438    arg_types = {"this": False, "options": False}
5439    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5443class JSONArrayContains(Binary, Predicate, Func):
5444    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5447class ParseJSON(Func):
5448    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5449    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5450    arg_types = {"this": True, "expressions": False}
5451    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5454class Least(Func):
5455    arg_types = {"this": True, "expressions": False}
5456    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5459class Left(Func):
5460    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5467class Length(Func):
5468    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5471class Levenshtein(Func):
5472    arg_types = {
5473        "this": True,
5474        "expression": False,
5475        "ins_cost": False,
5476        "del_cost": False,
5477        "sub_cost": False,
5478    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5481class Ln(Func):
5482    pass
key = 'ln'
class Log(Func):
5485class Log(Func):
5486    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5489class LogicalOr(AggFunc):
5490    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5493class LogicalAnd(AggFunc):
5494    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5497class Lower(Func):
5498    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5501class Map(Func):
5502    arg_types = {"keys": False, "values": False}
5503
5504    @property
5505    def keys(self) -> t.List[Expression]:
5506        keys = self.args.get("keys")
5507        return keys.expressions if keys else []
5508
5509    @property
5510    def values(self) -> t.List[Expression]:
5511        values = self.args.get("values")
5512        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5504    @property
5505    def keys(self) -> t.List[Expression]:
5506        keys = self.args.get("keys")
5507        return keys.expressions if keys else []
values: List[Expression]
5509    @property
5510    def values(self) -> t.List[Expression]:
5511        values = self.args.get("values")
5512        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5516class ToMap(Func):
5517    pass
key = 'tomap'
class MapFromEntries(Func):
5520class MapFromEntries(Func):
5521    pass
key = 'mapfromentries'
class StarMap(Func):
5524class StarMap(Func):
5525    pass
key = 'starmap'
class VarMap(Func):
5528class VarMap(Func):
5529    arg_types = {"keys": True, "values": True}
5530    is_var_len_args = True
5531
5532    @property
5533    def keys(self) -> t.List[Expression]:
5534        return self.args["keys"].expressions
5535
5536    @property
5537    def values(self) -> t.List[Expression]:
5538        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5532    @property
5533    def keys(self) -> t.List[Expression]:
5534        return self.args["keys"].expressions
values: List[Expression]
5536    @property
5537    def values(self) -> t.List[Expression]:
5538        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5542class MatchAgainst(Func):
5543    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5546class Max(AggFunc):
5547    arg_types = {"this": True, "expressions": False}
5548    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5551class MD5(Func):
5552    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5556class MD5Digest(Func):
5557    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5560class Min(AggFunc):
5561    arg_types = {"this": True, "expressions": False}
5562    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5565class Month(Func):
5566    pass
key = 'month'
class AddMonths(Func):
5569class AddMonths(Func):
5570    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5573class Nvl2(Func):
5574    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5578class Predict(Func):
5579    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5582class Pow(Binary, Func):
5583    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5586class PercentileCont(AggFunc):
5587    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5590class PercentileDisc(AggFunc):
5591    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5594class Quantile(AggFunc):
5595    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5598class ApproxQuantile(Quantile):
5599    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
5602class Quarter(Func):
5603    pass
key = 'quarter'
class Rand(Func):
5606class Rand(Func):
5607    _sql_names = ["RAND", "RANDOM"]
5608    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5611class Randn(Func):
5612    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5615class RangeN(Func):
5616    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5619class ReadCSV(Func):
5620    _sql_names = ["READ_CSV"]
5621    is_var_len_args = True
5622    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5625class Reduce(Func):
5626    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):
5629class RegexpExtract(Func):
5630    arg_types = {
5631        "this": True,
5632        "expression": True,
5633        "position": False,
5634        "occurrence": False,
5635        "parameters": False,
5636        "group": False,
5637    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5640class RegexpReplace(Func):
5641    arg_types = {
5642        "this": True,
5643        "expression": True,
5644        "replacement": False,
5645        "position": False,
5646        "occurrence": False,
5647        "modifiers": False,
5648    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5651class RegexpLike(Binary, Func):
5652    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5655class RegexpILike(Binary, Func):
5656    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5661class RegexpSplit(Func):
5662    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5665class Repeat(Func):
5666    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5671class Round(Func):
5672    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5675class RowNumber(Func):
5676    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5679class SafeDivide(Func):
5680    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5683class SHA(Func):
5684    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5687class SHA2(Func):
5688    _sql_names = ["SHA2"]
5689    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5692class Sign(Func):
5693    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5696class SortArray(Func):
5697    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5700class Split(Func):
5701    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5706class Substring(Func):
5707    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5710class StandardHash(Func):
5711    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5714class StartsWith(Func):
5715    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5716    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5719class StrPosition(Func):
5720    arg_types = {
5721        "this": True,
5722        "substr": True,
5723        "position": False,
5724        "instance": False,
5725    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5728class StrToDate(Func):
5729    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5732class StrToTime(Func):
5733    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5738class StrToUnix(Func):
5739    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5744class StrToMap(Func):
5745    arg_types = {
5746        "this": True,
5747        "pair_delim": False,
5748        "key_value_delim": False,
5749        "duplicate_resolution_callback": False,
5750    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5753class NumberToStr(Func):
5754    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5757class FromBase(Func):
5758    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5761class Struct(Func):
5762    arg_types = {"expressions": False}
5763    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5766class StructExtract(Func):
5767    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5772class Stuff(Func):
5773    _sql_names = ["STUFF", "INSERT"]
5774    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):
5777class Sum(AggFunc):
5778    pass
key = 'sum'
class Sqrt(Func):
5781class Sqrt(Func):
5782    pass
key = 'sqrt'
class Stddev(AggFunc):
5785class Stddev(AggFunc):
5786    pass
key = 'stddev'
class StddevPop(AggFunc):
5789class StddevPop(AggFunc):
5790    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5793class StddevSamp(AggFunc):
5794    pass
key = 'stddevsamp'
class TimeToStr(Func):
5797class TimeToStr(Func):
5798    arg_types = {"this": True, "format": True, "culture": False, "timezone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'timezone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5801class TimeToTimeStr(Func):
5802    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5805class TimeToUnix(Func):
5806    pass
key = 'timetounix'
class TimeStrToDate(Func):
5809class TimeStrToDate(Func):
5810    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5813class TimeStrToTime(Func):
5814    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5817class TimeStrToUnix(Func):
5818    pass
key = 'timestrtounix'
class Trim(Func):
5821class Trim(Func):
5822    arg_types = {
5823        "this": True,
5824        "expression": False,
5825        "position": False,
5826        "collation": False,
5827    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5830class TsOrDsAdd(Func, TimeUnit):
5831    # return_type is used to correctly cast the arguments of this expression when transpiling it
5832    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5833
5834    @property
5835    def return_type(self) -> DataType:
5836        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
5834    @property
5835    def return_type(self) -> DataType:
5836        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5839class TsOrDsDiff(Func, TimeUnit):
5840    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5843class TsOrDsToDateStr(Func):
5844    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5847class TsOrDsToDate(Func):
5848    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5851class TsOrDsToTime(Func):
5852    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5855class TsOrDsToTimestamp(Func):
5856    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5859class TsOrDiToDi(Func):
5860    pass
key = 'tsorditodi'
class Unhex(Func):
5863class Unhex(Func):
5864    pass
key = 'unhex'
class UnixDate(Func):
5868class UnixDate(Func):
5869    pass
key = 'unixdate'
class UnixToStr(Func):
5872class UnixToStr(Func):
5873    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5878class UnixToTime(Func):
5879    arg_types = {
5880        "this": True,
5881        "scale": False,
5882        "zone": False,
5883        "hours": False,
5884        "minutes": False,
5885        "format": False,
5886    }
5887
5888    SECONDS = Literal.number(0)
5889    DECIS = Literal.number(1)
5890    CENTIS = Literal.number(2)
5891    MILLIS = Literal.number(3)
5892    DECIMILLIS = Literal.number(4)
5893    CENTIMILLIS = Literal.number(5)
5894    MICROS = Literal.number(6)
5895    DECIMICROS = Literal.number(7)
5896    CENTIMICROS = Literal.number(8)
5897    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):
5900class UnixToTimeStr(Func):
5901    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5904class TimestampFromParts(Func):
5905    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5906    arg_types = {
5907        "year": True,
5908        "month": True,
5909        "day": True,
5910        "hour": True,
5911        "min": True,
5912        "sec": True,
5913        "nano": False,
5914        "zone": False,
5915        "milli": False,
5916    }
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):
5919class Upper(Func):
5920    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5923class Corr(Binary, AggFunc):
5924    pass
key = 'corr'
class Variance(AggFunc):
5927class Variance(AggFunc):
5928    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5931class VariancePop(AggFunc):
5932    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5935class CovarSamp(Binary, AggFunc):
5936    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5939class CovarPop(Binary, AggFunc):
5940    pass
key = 'covarpop'
class Week(Func):
5943class Week(Func):
5944    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5947class XMLTable(Func):
5948    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
arg_types = {'this': True, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class Year(Func):
5951class Year(Func):
5952    pass
key = 'year'
class Use(Expression):
5955class Use(Expression):
5956    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5959class Merge(Expression):
5960    arg_types = {
5961        "this": True,
5962        "using": True,
5963        "on": True,
5964        "expressions": True,
5965        "with": False,
5966    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5969class When(Func):
5970    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class NextValueFor(Func):
5975class NextValueFor(Func):
5976    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
5981class Semicolon(Expression):
5982    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_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'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, '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'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <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'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, '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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6022def maybe_parse(
6023    sql_or_expression: ExpOrStr,
6024    *,
6025    into: t.Optional[IntoType] = None,
6026    dialect: DialectType = None,
6027    prefix: t.Optional[str] = None,
6028    copy: bool = False,
6029    **opts,
6030) -> Expression:
6031    """Gracefully handle a possible string or expression.
6032
6033    Example:
6034        >>> maybe_parse("1")
6035        Literal(this=1, is_string=False)
6036        >>> maybe_parse(to_identifier("x"))
6037        Identifier(this=x, quoted=False)
6038
6039    Args:
6040        sql_or_expression: the SQL code string or an expression
6041        into: the SQLGlot Expression to parse into
6042        dialect: the dialect used to parse the input expressions (in the case that an
6043            input expression is a SQL string).
6044        prefix: a string to prefix the sql with before it gets parsed
6045            (automatically includes a space)
6046        copy: whether to copy the expression.
6047        **opts: other options to use to parse the input expressions (again, in the case
6048            that an input expression is a SQL string).
6049
6050    Returns:
6051        Expression: the parsed or given expression.
6052    """
6053    if isinstance(sql_or_expression, Expression):
6054        if copy:
6055            return sql_or_expression.copy()
6056        return sql_or_expression
6057
6058    if sql_or_expression is None:
6059        raise ParseError("SQL cannot be None")
6060
6061    import sqlglot
6062
6063    sql = str(sql_or_expression)
6064    if prefix:
6065        sql = f"{prefix} {sql}"
6066
6067    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):
6078def maybe_copy(instance, copy=True):
6079    return instance.copy() if copy and instance else instance
def union( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
6293def union(
6294    left: ExpOrStr,
6295    right: ExpOrStr,
6296    distinct: bool = True,
6297    dialect: DialectType = None,
6298    copy: bool = True,
6299    **opts,
6300) -> Union:
6301    """
6302    Initializes a syntax tree from one UNION expression.
6303
6304    Example:
6305        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6306        'SELECT * FROM foo UNION SELECT * FROM bla'
6307
6308    Args:
6309        left: the SQL code string corresponding to the left-hand side.
6310            If an `Expression` instance is passed, it will be used as-is.
6311        right: the SQL code string corresponding to the right-hand side.
6312            If an `Expression` instance is passed, it will be used as-is.
6313        distinct: set the DISTINCT flag if and only if this is true.
6314        dialect: the dialect used to parse the input expression.
6315        copy: whether to copy the expression.
6316        opts: other options to use to parse the input expressions.
6317
6318    Returns:
6319        The new Union instance.
6320    """
6321    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6322    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6323
6324    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
6327def intersect(
6328    left: ExpOrStr,
6329    right: ExpOrStr,
6330    distinct: bool = True,
6331    dialect: DialectType = None,
6332    copy: bool = True,
6333    **opts,
6334) -> Intersect:
6335    """
6336    Initializes a syntax tree from one INTERSECT expression.
6337
6338    Example:
6339        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6340        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6341
6342    Args:
6343        left: the SQL code string corresponding to the left-hand side.
6344            If an `Expression` instance is passed, it will be used as-is.
6345        right: the SQL code string corresponding to the right-hand side.
6346            If an `Expression` instance is passed, it will be used as-is.
6347        distinct: set the DISTINCT flag if and only if this is true.
6348        dialect: the dialect used to parse the input expression.
6349        copy: whether to copy the expression.
6350        opts: other options to use to parse the input expressions.
6351
6352    Returns:
6353        The new Intersect instance.
6354    """
6355    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6356    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6357
6358    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
6361def except_(
6362    left: ExpOrStr,
6363    right: ExpOrStr,
6364    distinct: bool = True,
6365    dialect: DialectType = None,
6366    copy: bool = True,
6367    **opts,
6368) -> Except:
6369    """
6370    Initializes a syntax tree from one EXCEPT expression.
6371
6372    Example:
6373        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6374        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6375
6376    Args:
6377        left: the SQL code string corresponding to the left-hand side.
6378            If an `Expression` instance is passed, it will be used as-is.
6379        right: the SQL code string corresponding to the right-hand side.
6380            If an `Expression` instance is passed, it will be used as-is.
6381        distinct: set the DISTINCT flag if and only if this is true.
6382        dialect: the dialect used to parse the input expression.
6383        copy: whether to copy the expression.
6384        opts: other options to use to parse the input expressions.
6385
6386    Returns:
6387        The new Except instance.
6388    """
6389    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6390    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6391
6392    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6395def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6396    """
6397    Initializes a syntax tree from one or multiple SELECT expressions.
6398
6399    Example:
6400        >>> select("col1", "col2").from_("tbl").sql()
6401        'SELECT col1, col2 FROM tbl'
6402
6403    Args:
6404        *expressions: the SQL code string to parse as the expressions of a
6405            SELECT statement. If an Expression instance is passed, this is used as-is.
6406        dialect: the dialect used to parse the input expressions (in the case that an
6407            input expression is a SQL string).
6408        **opts: other options to use to parse the input expressions (again, in the case
6409            that an input expression is a SQL string).
6410
6411    Returns:
6412        Select: the syntax tree for the SELECT statement.
6413    """
6414    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6417def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6418    """
6419    Initializes a syntax tree from a FROM expression.
6420
6421    Example:
6422        >>> from_("tbl").select("col1", "col2").sql()
6423        'SELECT col1, col2 FROM tbl'
6424
6425    Args:
6426        *expression: the SQL code string to parse as the FROM expressions of a
6427            SELECT statement. If an Expression instance is passed, this is used as-is.
6428        dialect: the dialect used to parse the input expression (in the case that the
6429            input expression is a SQL string).
6430        **opts: other options to use to parse the input expressions (again, in the case
6431            that the input expression is a SQL string).
6432
6433    Returns:
6434        Select: the syntax tree for the SELECT statement.
6435    """
6436    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: dict, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Update:
6439def update(
6440    table: str | Table,
6441    properties: dict,
6442    where: t.Optional[ExpOrStr] = None,
6443    from_: t.Optional[ExpOrStr] = None,
6444    dialect: DialectType = None,
6445    **opts,
6446) -> Update:
6447    """
6448    Creates an update statement.
6449
6450    Example:
6451        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6452        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6453
6454    Args:
6455        *properties: dictionary of properties to set which are
6456            auto converted to sql objects eg None -> NULL
6457        where: sql conditional parsed into a WHERE statement
6458        from_: sql statement parsed into a FROM statement
6459        dialect: the dialect used to parse the input expressions.
6460        **opts: other options to use to parse the input expressions.
6461
6462    Returns:
6463        Update: the syntax tree for the UPDATE statement.
6464    """
6465    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6466    update_expr.set(
6467        "expressions",
6468        [
6469            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6470            for k, v in properties.items()
6471        ],
6472    )
6473    if from_:
6474        update_expr.set(
6475            "from",
6476            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6477        )
6478    if isinstance(where, Condition):
6479        where = Where(this=where)
6480    if where:
6481        update_expr.set(
6482            "where",
6483            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6484        )
6485    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
"UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
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
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Delete:
6488def delete(
6489    table: ExpOrStr,
6490    where: t.Optional[ExpOrStr] = None,
6491    returning: t.Optional[ExpOrStr] = None,
6492    dialect: DialectType = None,
6493    **opts,
6494) -> Delete:
6495    """
6496    Builds a delete statement.
6497
6498    Example:
6499        >>> delete("my_table", where="id > 1").sql()
6500        'DELETE FROM my_table WHERE id > 1'
6501
6502    Args:
6503        where: sql conditional parsed into a WHERE statement
6504        returning: sql conditional parsed into a RETURNING statement
6505        dialect: the dialect used to parse the input expressions.
6506        **opts: other options to use to parse the input expressions.
6507
6508    Returns:
6509        Delete: the syntax tree for the DELETE statement.
6510    """
6511    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6512    if where:
6513        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6514    if returning:
6515        delete_expr = t.cast(
6516            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6517        )
6518    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
6521def insert(
6522    expression: ExpOrStr,
6523    into: ExpOrStr,
6524    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6525    overwrite: t.Optional[bool] = None,
6526    returning: t.Optional[ExpOrStr] = None,
6527    dialect: DialectType = None,
6528    copy: bool = True,
6529    **opts,
6530) -> Insert:
6531    """
6532    Builds an INSERT statement.
6533
6534    Example:
6535        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6536        'INSERT INTO tbl VALUES (1, 2, 3)'
6537
6538    Args:
6539        expression: the sql string or expression of the INSERT statement
6540        into: the tbl to insert data to.
6541        columns: optionally the table's column names.
6542        overwrite: whether to INSERT OVERWRITE or not.
6543        returning: sql conditional parsed into a RETURNING statement
6544        dialect: the dialect used to parse the input expressions.
6545        copy: whether to copy the expression.
6546        **opts: other options to use to parse the input expressions.
6547
6548    Returns:
6549        Insert: the syntax tree for the INSERT statement.
6550    """
6551    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6552    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6553
6554    if columns:
6555        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6556
6557    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6558
6559    if returning:
6560        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6561
6562    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 condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6565def condition(
6566    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6567) -> Condition:
6568    """
6569    Initialize a logical condition expression.
6570
6571    Example:
6572        >>> condition("x=1").sql()
6573        'x = 1'
6574
6575        This is helpful for composing larger logical syntax trees:
6576        >>> where = condition("x=1")
6577        >>> where = where.and_("y=1")
6578        >>> Select().from_("tbl").select("*").where(where).sql()
6579        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6580
6581    Args:
6582        *expression: the SQL code string to parse.
6583            If an Expression instance is passed, this is used as-is.
6584        dialect: the dialect used to parse the input expression (in the case that the
6585            input expression is a SQL string).
6586        copy: Whether to copy `expression` (only applies to expressions).
6587        **opts: other options to use to parse the input expressions (again, in the case
6588            that the input expression is a SQL string).
6589
6590    Returns:
6591        The new Condition instance
6592    """
6593    return maybe_parse(
6594        expression,
6595        into=Condition,
6596        dialect=dialect,
6597        copy=copy,
6598        **opts,
6599    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6602def and_(
6603    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6604) -> Condition:
6605    """
6606    Combine multiple conditions with an AND logical operator.
6607
6608    Example:
6609        >>> and_("x=1", and_("y=1", "z=1")).sql()
6610        'x = 1 AND (y = 1 AND z = 1)'
6611
6612    Args:
6613        *expressions: the SQL code strings to parse.
6614            If an Expression instance is passed, this is used as-is.
6615        dialect: the dialect used to parse the input expression.
6616        copy: whether to copy `expressions` (only applies to Expressions).
6617        **opts: other options to use to parse the input expressions.
6618
6619    Returns:
6620        The new condition
6621    """
6622    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **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).
  • **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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6625def or_(
6626    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6627) -> Condition:
6628    """
6629    Combine multiple conditions with an OR logical operator.
6630
6631    Example:
6632        >>> or_("x=1", or_("y=1", "z=1")).sql()
6633        'x = 1 OR (y = 1 OR z = 1)'
6634
6635    Args:
6636        *expressions: the SQL code strings to parse.
6637            If an Expression instance is passed, this is used as-is.
6638        dialect: the dialect used to parse the input expression.
6639        copy: whether to copy `expressions` (only applies to Expressions).
6640        **opts: other options to use to parse the input expressions.
6641
6642    Returns:
6643        The new condition
6644    """
6645    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **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).
  • **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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6648def xor(
6649    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6650) -> Condition:
6651    """
6652    Combine multiple conditions with an XOR logical operator.
6653
6654    Example:
6655        >>> xor("x=1", xor("y=1", "z=1")).sql()
6656        'x = 1 XOR (y = 1 XOR z = 1)'
6657
6658    Args:
6659        *expressions: the SQL code strings to parse.
6660            If an Expression instance is passed, this is used as-is.
6661        dialect: the dialect used to parse the input expression.
6662        copy: whether to copy `expressions` (only applies to Expressions).
6663        **opts: other options to use to parse the input expressions.
6664
6665    Returns:
6666        The new condition
6667    """
6668    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, **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).
  • **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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
6671def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6672    """
6673    Wrap a condition with a NOT operator.
6674
6675    Example:
6676        >>> not_("this_suit='black'").sql()
6677        "NOT this_suit = 'black'"
6678
6679    Args:
6680        expression: the SQL code string to parse.
6681            If an Expression instance is passed, this is used as-is.
6682        dialect: the dialect used to parse the input expression.
6683        copy: whether to copy the expression or not.
6684        **opts: other options to use to parse the input expressions.
6685
6686    Returns:
6687        The new condition.
6688    """
6689    this = condition(
6690        expression,
6691        dialect=dialect,
6692        copy=copy,
6693        **opts,
6694    )
6695    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:
6698def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6699    """
6700    Wrap an expression in parentheses.
6701
6702    Example:
6703        >>> paren("5 + 3").sql()
6704        '(5 + 3)'
6705
6706    Args:
6707        expression: the SQL code string to parse.
6708            If an Expression instance is passed, this is used as-is.
6709        copy: whether to copy the expression or not.
6710
6711    Returns:
6712        The wrapped expression.
6713    """
6714    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):
6730def to_identifier(name, quoted=None, copy=True):
6731    """Builds an identifier.
6732
6733    Args:
6734        name: The name to turn into an identifier.
6735        quoted: Whether to force quote the identifier.
6736        copy: Whether to copy name if it's an Identifier.
6737
6738    Returns:
6739        The identifier ast node.
6740    """
6741
6742    if name is None:
6743        return None
6744
6745    if isinstance(name, Identifier):
6746        identifier = maybe_copy(name, copy)
6747    elif isinstance(name, str):
6748        identifier = Identifier(
6749            this=name,
6750            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6751        )
6752    else:
6753        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6754    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
6757def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6758    """
6759    Parses a given string into an identifier.
6760
6761    Args:
6762        name: The name to parse into an identifier.
6763        dialect: The dialect to parse against.
6764
6765    Returns:
6766        The identifier ast node.
6767    """
6768    try:
6769        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6770    except ParseError:
6771        expression = to_identifier(name)
6772
6773    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*([0-9]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
6779def to_interval(interval: str | Literal) -> Interval:
6780    """Builds an interval expression from a string like '1 day' or '5 months'."""
6781    if isinstance(interval, Literal):
6782        if not interval.is_string:
6783            raise ValueError("Invalid interval string.")
6784
6785        interval = interval.this
6786
6787    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6788
6789    if not interval_parts:
6790        raise ValueError("Invalid interval string.")
6791
6792    return Interval(
6793        this=Literal.string(interval_parts.group(1)),
6794        unit=Var(this=interval_parts.group(2).upper()),
6795    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
6798def to_table(
6799    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6800) -> Table:
6801    """
6802    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6803    If a table is passed in then that table is returned.
6804
6805    Args:
6806        sql_path: a `[catalog].[schema].[table]` string.
6807        dialect: the source dialect according to which the table name will be parsed.
6808        copy: Whether to copy a table if it is passed in.
6809        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6810
6811    Returns:
6812        A table expression.
6813    """
6814    if isinstance(sql_path, Table):
6815        return maybe_copy(sql_path, copy=copy)
6816
6817    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6818
6819    for k, v in kwargs.items():
6820        table.set(k, v)
6821
6822    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
6825def to_column(
6826    sql_path: str | Column,
6827    quoted: t.Optional[bool] = None,
6828    dialect: DialectType = None,
6829    copy: bool = True,
6830    **kwargs,
6831) -> Column:
6832    """
6833    Create a column from a `[table].[column]` sql path. Table is optional.
6834    If a column is passed in then that column is returned.
6835
6836    Args:
6837        sql_path: a `[table].[column]` string.
6838        quoted: Whether or not to force quote identifiers.
6839        dialect: the source dialect according to which the column name will be parsed.
6840        copy: Whether to copy a column if it is passed in.
6841        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6842
6843    Returns:
6844        A column expression.
6845    """
6846    if isinstance(sql_path, Column):
6847        return maybe_copy(sql_path, copy=copy)
6848
6849    try:
6850        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6851    except ParseError:
6852        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6853
6854    for k, v in kwargs.items():
6855        col.set(k, v)
6856
6857    if quoted:
6858        for i in col.find_all(Identifier):
6859            i.set("quoted", True)
6860
6861    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
6864def alias_(
6865    expression: ExpOrStr,
6866    alias: t.Optional[str | Identifier],
6867    table: bool | t.Sequence[str | Identifier] = False,
6868    quoted: t.Optional[bool] = None,
6869    dialect: DialectType = None,
6870    copy: bool = True,
6871    **opts,
6872):
6873    """Create an Alias expression.
6874
6875    Example:
6876        >>> alias_('foo', 'bar').sql()
6877        'foo AS bar'
6878
6879        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6880        '(SELECT 1, 2) AS bar(a, b)'
6881
6882    Args:
6883        expression: the SQL code strings to parse.
6884            If an Expression instance is passed, this is used as-is.
6885        alias: the alias name to use. If the name has
6886            special characters it is quoted.
6887        table: Whether to create a table alias, can also be a list of columns.
6888        quoted: whether to quote the alias
6889        dialect: the dialect used to parse the input expression.
6890        copy: Whether to copy the expression.
6891        **opts: other options to use to parse the input expressions.
6892
6893    Returns:
6894        Alias: the aliased expression
6895    """
6896    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6897    alias = to_identifier(alias, quoted=quoted)
6898
6899    if table:
6900        table_alias = TableAlias(this=alias)
6901        exp.set("alias", table_alias)
6902
6903        if not isinstance(table, bool):
6904            for column in table:
6905                table_alias.append("columns", to_identifier(column, quoted=quoted))
6906
6907        return exp
6908
6909    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6910    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6911    # for the complete Window expression.
6912    #
6913    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6914
6915    if "alias" in exp.arg_types and not isinstance(exp, Window):
6916        exp.set("alias", alias)
6917        return exp
6918    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6921def subquery(
6922    expression: ExpOrStr,
6923    alias: t.Optional[Identifier | str] = None,
6924    dialect: DialectType = None,
6925    **opts,
6926) -> Select:
6927    """
6928    Build a subquery expression that's selected from.
6929
6930    Example:
6931        >>> subquery('select x from tbl', 'bar').select('x').sql()
6932        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6933
6934    Args:
6935        expression: the SQL code strings to parse.
6936            If an Expression instance is passed, this is used as-is.
6937        alias: the alias name to use.
6938        dialect: the dialect used to parse the input expression.
6939        **opts: other options to use to parse the input expressions.
6940
6941    Returns:
6942        A new Select instance with the subquery expression included.
6943    """
6944
6945    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
6946    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):
6977def column(
6978    col,
6979    table=None,
6980    db=None,
6981    catalog=None,
6982    *,
6983    fields=None,
6984    quoted=None,
6985    copy=True,
6986):
6987    """
6988    Build a Column.
6989
6990    Args:
6991        col: Column name.
6992        table: Table name.
6993        db: Database name.
6994        catalog: Catalog name.
6995        fields: Additional fields using dots.
6996        quoted: Whether to force quotes on the column's identifiers.
6997        copy: Whether to copy identifiers if passed in.
6998
6999    Returns:
7000        The new Column instance.
7001    """
7002    this = Column(
7003        this=to_identifier(col, quoted=quoted, copy=copy),
7004        table=to_identifier(table, quoted=quoted, copy=copy),
7005        db=to_identifier(db, quoted=quoted, copy=copy),
7006        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7007    )
7008
7009    if fields:
7010        this = Dot.build(
7011            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7012        )
7013    return this

Build a Column.

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

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, **opts) -> Cast:
7016def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7017    """Cast an expression to a data type.
7018
7019    Example:
7020        >>> cast('x + 1', 'int').sql()
7021        'CAST(x + 1 AS INT)'
7022
7023    Args:
7024        expression: The expression to cast.
7025        to: The datatype to cast to.
7026        copy: Whether to copy the supplied expressions.
7027
7028    Returns:
7029        The new Cast instance.
7030    """
7031    expr = maybe_parse(expression, copy=copy, **opts)
7032    data_type = DataType.build(to, copy=copy, **opts)
7033
7034    if expr.is_type(data_type):
7035        return expr
7036
7037    expr = Cast(this=expr, to=data_type)
7038    expr.type = data_type
7039
7040    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.
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:
7043def table_(
7044    table: Identifier | str,
7045    db: t.Optional[Identifier | str] = None,
7046    catalog: t.Optional[Identifier | str] = None,
7047    quoted: t.Optional[bool] = None,
7048    alias: t.Optional[Identifier | str] = None,
7049) -> Table:
7050    """Build a Table.
7051
7052    Args:
7053        table: Table name.
7054        db: Database name.
7055        catalog: Catalog name.
7056        quote: Whether to force quotes on the table's identifiers.
7057        alias: Table's alias.
7058
7059    Returns:
7060        The new Table instance.
7061    """
7062    return Table(
7063        this=to_identifier(table, quoted=quoted) if table else None,
7064        db=to_identifier(db, quoted=quoted) if db else None,
7065        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7066        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7067    )

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:
7070def values(
7071    values: t.Iterable[t.Tuple[t.Any, ...]],
7072    alias: t.Optional[str] = None,
7073    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7074) -> Values:
7075    """Build VALUES statement.
7076
7077    Example:
7078        >>> values([(1, '2')]).sql()
7079        "VALUES (1, '2')"
7080
7081    Args:
7082        values: values statements that will be converted to SQL
7083        alias: optional alias
7084        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7085         If either are provided then an alias is also required.
7086
7087    Returns:
7088        Values: the Values expression object
7089    """
7090    if columns and not alias:
7091        raise ValueError("Alias is required when providing columns")
7092
7093    return Values(
7094        expressions=[convert(tup) for tup in values],
7095        alias=(
7096            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7097            if columns
7098            else (TableAlias(this=to_identifier(alias)) if alias else None)
7099        ),
7100    )

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:
7103def var(name: t.Optional[ExpOrStr]) -> Var:
7104    """Build a SQL variable.
7105
7106    Example:
7107        >>> repr(var('x'))
7108        'Var(this=x)'
7109
7110        >>> repr(var(column('x', table='y')))
7111        'Var(this=x)'
7112
7113    Args:
7114        name: The name of the var or an expression who's name will become the var.
7115
7116    Returns:
7117        The new variable node.
7118    """
7119    if not name:
7120        raise ValueError("Cannot convert empty name into var.")
7121
7122    if isinstance(name, Expression):
7123        name = name.name
7124    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7127def rename_table(
7128    old_name: str | Table,
7129    new_name: str | Table,
7130    dialect: DialectType = None,
7131) -> AlterTable:
7132    """Build ALTER TABLE... RENAME... expression
7133
7134    Args:
7135        old_name: The old name of the table
7136        new_name: The new name of the table
7137        dialect: The dialect to parse the table.
7138
7139    Returns:
7140        Alter table expression
7141    """
7142    old_table = to_table(old_name, dialect=dialect)
7143    new_table = to_table(new_name, dialect=dialect)
7144    return AlterTable(
7145        this=old_table,
7146        actions=[
7147            RenameTable(this=new_table),
7148        ],
7149    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7152def rename_column(
7153    table_name: str | Table,
7154    old_column_name: str | Column,
7155    new_column_name: str | Column,
7156    exists: t.Optional[bool] = None,
7157    dialect: DialectType = None,
7158) -> AlterTable:
7159    """Build ALTER TABLE... RENAME COLUMN... expression
7160
7161    Args:
7162        table_name: Name of the table
7163        old_column: The old name of the column
7164        new_column: The new name of the column
7165        exists: Whether to add the `IF EXISTS` clause
7166        dialect: The dialect to parse the table/column.
7167
7168    Returns:
7169        Alter table expression
7170    """
7171    table = to_table(table_name, dialect=dialect)
7172    old_column = to_column(old_column_name, dialect=dialect)
7173    new_column = to_column(new_column_name, dialect=dialect)
7174    return AlterTable(
7175        this=table,
7176        actions=[
7177            RenameColumn(this=old_column, to=new_column, exists=exists),
7178        ],
7179    )

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:
7182def convert(value: t.Any, copy: bool = False) -> Expression:
7183    """Convert a python value into an expression object.
7184
7185    Raises an error if a conversion is not possible.
7186
7187    Args:
7188        value: A python object.
7189        copy: Whether to copy `value` (only applies to Expressions and collections).
7190
7191    Returns:
7192        The equivalent expression object.
7193    """
7194    if isinstance(value, Expression):
7195        return maybe_copy(value, copy)
7196    if isinstance(value, str):
7197        return Literal.string(value)
7198    if isinstance(value, bool):
7199        return Boolean(this=value)
7200    if value is None or (isinstance(value, float) and math.isnan(value)):
7201        return null()
7202    if isinstance(value, numbers.Number):
7203        return Literal.number(value)
7204    if isinstance(value, bytes):
7205        return HexString(this=value.hex())
7206    if isinstance(value, datetime.datetime):
7207        datetime_literal = Literal.string(
7208            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7209                sep=" "
7210            )
7211        )
7212        return TimeStrToTime(this=datetime_literal)
7213    if isinstance(value, datetime.date):
7214        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7215        return DateStrToDate(this=date_literal)
7216    if isinstance(value, tuple):
7217        if hasattr(value, "_fields"):
7218            return Struct(
7219                expressions=[
7220                    PropertyEQ(
7221                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7222                    )
7223                    for k in value._fields
7224                ]
7225            )
7226        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7227    if isinstance(value, list):
7228        return Array(expressions=[convert(v, copy=copy) for v in value])
7229    if isinstance(value, dict):
7230        return Map(
7231            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7232            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7233        )
7234    if hasattr(value, "__dict__"):
7235        return Struct(
7236            expressions=[
7237                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7238                for k, v in value.__dict__.items()
7239            ]
7240        )
7241    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:
7244def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7245    """
7246    Replace children of an expression with the result of a lambda fun(child) -> exp.
7247    """
7248    for k, v in tuple(expression.args.items()):
7249        is_list_arg = type(v) is list
7250
7251        child_nodes = v if is_list_arg else [v]
7252        new_child_nodes = []
7253
7254        for cn in child_nodes:
7255            if isinstance(cn, Expression):
7256                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7257                    new_child_nodes.append(child_node)
7258            else:
7259                new_child_nodes.append(cn)
7260
7261        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:
7264def replace_tree(
7265    expression: Expression,
7266    fun: t.Callable,
7267    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7268) -> Expression:
7269    """
7270    Replace an entire tree with the result of function calls on each node.
7271
7272    This will be traversed in reverse dfs, so leaves first.
7273    If new nodes are created as a result of function calls, they will also be traversed.
7274    """
7275    stack = list(expression.dfs(prune=prune))
7276
7277    while stack:
7278        node = stack.pop()
7279        new_node = fun(node)
7280
7281        if new_node is not node:
7282            node.replace(new_node)
7283
7284            if isinstance(new_node, Expression):
7285                stack.append(new_node)
7286
7287    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]:
7290def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7291    """
7292    Return all table names referenced through columns in an expression.
7293
7294    Example:
7295        >>> import sqlglot
7296        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7297        ['a', 'c']
7298
7299    Args:
7300        expression: expression to find table names.
7301        exclude: a table name to exclude
7302
7303    Returns:
7304        A list of unique names.
7305    """
7306    return {
7307        table
7308        for table in (column.table for column in expression.find_all(Column))
7309        if table and table != exclude
7310    }

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
7313def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7314    """Get the full name of a table as a string.
7315
7316    Args:
7317        table: Table expression node or string.
7318        dialect: The dialect to generate the table name for.
7319        identify: Determines when an identifier should be quoted. Possible values are:
7320            False (default): Never quote, except in cases where it's mandatory by the dialect.
7321            True: Always quote.
7322
7323    Examples:
7324        >>> from sqlglot import exp, parse_one
7325        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7326        'a.b.c'
7327
7328    Returns:
7329        The table name.
7330    """
7331
7332    table = maybe_parse(table, into=Table, dialect=dialect)
7333
7334    if not table:
7335        raise ValueError(f"Cannot parse {table}")
7336
7337    return ".".join(
7338        (
7339            part.sql(dialect=dialect, identify=True, copy=False)
7340            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7341            else part.name
7342        )
7343        for part in table.parts
7344    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
7347def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7348    """Returns a case normalized table name without quotes.
7349
7350    Args:
7351        table: the table to normalize
7352        dialect: the dialect to use for normalization rules
7353        copy: whether to copy the expression.
7354
7355    Examples:
7356        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7357        'A-B.c'
7358    """
7359    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7360
7361    return ".".join(
7362        p.name
7363        for p in normalize_identifiers(
7364            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7365        ).parts
7366    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
7369def replace_tables(
7370    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7371) -> E:
7372    """Replace all tables in expression according to the mapping.
7373
7374    Args:
7375        expression: expression node to be transformed and replaced.
7376        mapping: mapping of table names.
7377        dialect: the dialect of the mapping table
7378        copy: whether to copy the expression.
7379
7380    Examples:
7381        >>> from sqlglot import exp, parse_one
7382        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7383        'SELECT * FROM c /* a.b */'
7384
7385    Returns:
7386        The mapped expression.
7387    """
7388
7389    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7390
7391    def _replace_tables(node: Expression) -> Expression:
7392        if isinstance(node, Table):
7393            original = normalize_table_name(node, dialect=dialect)
7394            new_name = mapping.get(original)
7395
7396            if new_name:
7397                table = to_table(
7398                    new_name,
7399                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7400                    dialect=dialect,
7401                )
7402                table.add_comments([original])
7403                return table
7404        return node
7405
7406    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:
7409def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7410    """Replace placeholders in an expression.
7411
7412    Args:
7413        expression: expression node to be transformed and replaced.
7414        args: positional names that will substitute unnamed placeholders in the given order.
7415        kwargs: keyword arguments that will substitute named placeholders.
7416
7417    Examples:
7418        >>> from sqlglot import exp, parse_one
7419        >>> replace_placeholders(
7420        ...     parse_one("select * from :tbl where ? = ?"),
7421        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7422        ... ).sql()
7423        "SELECT * FROM foo WHERE str_col = 'b'"
7424
7425    Returns:
7426        The mapped expression.
7427    """
7428
7429    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7430        if isinstance(node, Placeholder):
7431            if node.this:
7432                new_name = kwargs.get(node.this)
7433                if new_name is not None:
7434                    return convert(new_name)
7435            else:
7436                try:
7437                    return convert(next(args))
7438                except StopIteration:
7439                    pass
7440        return node
7441
7442    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, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
7445def expand(
7446    expression: Expression,
7447    sources: t.Dict[str, Query],
7448    dialect: DialectType = None,
7449    copy: bool = True,
7450) -> Expression:
7451    """Transforms an expression by expanding all referenced sources into subqueries.
7452
7453    Examples:
7454        >>> from sqlglot import parse_one
7455        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7456        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7457
7458        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7459        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7460
7461    Args:
7462        expression: The expression to expand.
7463        sources: A dictionary of name to Queries.
7464        dialect: The dialect of the sources dict.
7465        copy: Whether to copy the expression during transformation. Defaults to True.
7466
7467    Returns:
7468        The transformed expression.
7469    """
7470    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7471
7472    def _expand(node: Expression):
7473        if isinstance(node, Table):
7474            name = normalize_table_name(node, dialect=dialect)
7475            source = sources.get(name)
7476            if source:
7477                subquery = source.subquery(node.alias or name)
7478                subquery.comments = [f"source: {name}"]
7479                return subquery.transform(_expand, copy=False)
7480        return node
7481
7482    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 dictionary of name to Queries.
  • dialect: The dialect of the sources dict.
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
7485def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7486    """
7487    Returns a Func expression.
7488
7489    Examples:
7490        >>> func("abs", 5).sql()
7491        'ABS(5)'
7492
7493        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7494        'CAST(5 AS DOUBLE)'
7495
7496    Args:
7497        name: the name of the function to build.
7498        args: the args used to instantiate the function of interest.
7499        copy: whether to copy the argument expressions.
7500        dialect: the source dialect.
7501        kwargs: the kwargs used to instantiate the function of interest.
7502
7503    Note:
7504        The arguments `args` and `kwargs` are mutually exclusive.
7505
7506    Returns:
7507        An instance of the function of interest, or an anonymous function, if `name` doesn't
7508        correspond to an existing `sqlglot.expressions.Func` class.
7509    """
7510    if args and kwargs:
7511        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7512
7513    from sqlglot.dialects.dialect import Dialect
7514
7515    dialect = Dialect.get_or_raise(dialect)
7516
7517    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7518    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7519
7520    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7521    if constructor:
7522        if converted:
7523            if "dialect" in constructor.__code__.co_varnames:
7524                function = constructor(converted, dialect=dialect)
7525            else:
7526                function = constructor(converted)
7527        elif constructor.__name__ == "from_arg_list":
7528            function = constructor.__self__(**kwargs)  # type: ignore
7529        else:
7530            constructor = FUNCTION_BY_NAME.get(name.upper())
7531            if constructor:
7532                function = constructor(**kwargs)
7533            else:
7534                raise ValueError(
7535                    f"Unable to convert '{name}' into a Func. Either manually construct "
7536                    "the Func expression of interest or parse the function call."
7537                )
7538    else:
7539        kwargs = kwargs or {"expressions": converted}
7540        function = Anonymous(this=name, **kwargs)
7541
7542    for error_message in function.error_messages(converted):
7543        raise ValueError(error_message)
7544
7545    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 Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
7548def case(
7549    expression: t.Optional[ExpOrStr] = None,
7550    **opts,
7551) -> Case:
7552    """
7553    Initialize a CASE statement.
7554
7555    Example:
7556        case().when("a = 1", "foo").else_("bar")
7557
7558    Args:
7559        expression: Optionally, the input expression (not all dialects support this)
7560        **opts: Extra keyword arguments for parsing `expression`
7561    """
7562    if expression is not None:
7563        this = maybe_parse(expression, **opts)
7564    else:
7565        this = None
7566    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
7569def array(
7570    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7571) -> Array:
7572    """
7573    Returns an array.
7574
7575    Examples:
7576        >>> array(1, 'x').sql()
7577        'ARRAY(1, x)'
7578
7579    Args:
7580        expressions: the expressions to add to the array.
7581        copy: whether to copy the argument expressions.
7582        dialect: the source dialect.
7583        kwargs: the kwargs used to instantiate the function of interest.
7584
7585    Returns:
7586        An array expression.
7587    """
7588    return Array(
7589        expressions=[
7590            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7591            for expression in expressions
7592        ]
7593    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
7596def tuple_(
7597    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7598) -> Tuple:
7599    """
7600    Returns an tuple.
7601
7602    Examples:
7603        >>> tuple_(1, 'x').sql()
7604        '(1, x)'
7605
7606    Args:
7607        expressions: the expressions to add to the tuple.
7608        copy: whether to copy the argument expressions.
7609        dialect: the source dialect.
7610        kwargs: the kwargs used to instantiate the function of interest.
7611
7612    Returns:
7613        A tuple expression.
7614    """
7615    return Tuple(
7616        expressions=[
7617            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7618            for expression in expressions
7619        ]
7620    )

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:
7623def true() -> Boolean:
7624    """
7625    Returns a true Boolean expression.
7626    """
7627    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7630def false() -> Boolean:
7631    """
7632    Returns a false Boolean expression.
7633    """
7634    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7637def null() -> Null:
7638    """
7639    Returns a Null expression.
7640    """
7641    return Null()

Returns a Null expression.

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