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

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:
1913    def where(
1914        self,
1915        *expressions: t.Optional[ExpOrStr],
1916        append: bool = True,
1917        dialect: DialectType = None,
1918        copy: bool = True,
1919        **opts,
1920    ) -> Delete:
1921        """
1922        Append to or set the WHERE expressions.
1923
1924        Example:
1925            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1926            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1927
1928        Args:
1929            *expressions: the SQL code strings to parse.
1930                If an `Expression` instance is passed, it will be used as-is.
1931                Multiple expressions are combined with an AND operator.
1932            append: if `True`, AND the new expressions to any existing expression.
1933                Otherwise, this resets the expression.
1934            dialect: the dialect used to parse the input expressions.
1935            copy: if `False`, modify this expression instance in-place.
1936            opts: other options to use to parse the input expressions.
1937
1938        Returns:
1939            Delete: the modified expression.
1940        """
1941        return _apply_conjunction_builder(
1942            *expressions,
1943            instance=self,
1944            arg="where",
1945            append=append,
1946            into=Where,
1947            dialect=dialect,
1948            copy=copy,
1949            **opts,
1950        )

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):
1953class Drop(Expression):
1954    arg_types = {
1955        "this": False,
1956        "kind": False,
1957        "expressions": False,
1958        "exists": False,
1959        "temporary": False,
1960        "materialized": False,
1961        "cascade": False,
1962        "constraints": False,
1963        "purge": False,
1964        "cluster": False,
1965    }
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):
1968class Filter(Expression):
1969    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1972class Check(Expression):
1973    pass
key = 'check'
class Connect(Expression):
1977class Connect(Expression):
1978    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
1981class CopyParameter(Expression):
1982    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'copyparameter'
class Copy(Expression):
1985class Copy(Expression):
1986    arg_types = {
1987        "this": True,
1988        "kind": True,
1989        "files": True,
1990        "credentials": False,
1991        "format": False,
1992        "params": False,
1993    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
1996class Credentials(Expression):
1997    arg_types = {
1998        "credentials": False,
1999        "encryption": False,
2000        "storage": False,
2001        "iam_role": False,
2002        "region": False,
2003    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2006class Prior(Expression):
2007    pass
key = 'prior'
class Directory(Expression):
2010class Directory(Expression):
2011    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2012    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2015class ForeignKey(Expression):
2016    arg_types = {
2017        "expressions": True,
2018        "reference": False,
2019        "delete": False,
2020        "update": False,
2021    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2024class ColumnPrefix(Expression):
2025    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2028class PrimaryKey(Expression):
2029    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2034class Into(Expression):
2035    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2038class From(Expression):
2039    @property
2040    def name(self) -> str:
2041        return self.this.name
2042
2043    @property
2044    def alias_or_name(self) -> str:
2045        return self.this.alias_or_name
name: str
2039    @property
2040    def name(self) -> str:
2041        return self.this.name
alias_or_name: str
2043    @property
2044    def alias_or_name(self) -> str:
2045        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2048class Having(Expression):
2049    pass
key = 'having'
class Hint(Expression):
2052class Hint(Expression):
2053    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2056class JoinHint(Expression):
2057    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2060class Identifier(Expression):
2061    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2062
2063    @property
2064    def quoted(self) -> bool:
2065        return bool(self.args.get("quoted"))
2066
2067    @property
2068    def hashable_args(self) -> t.Any:
2069        return (self.this, self.quoted)
2070
2071    @property
2072    def output_name(self) -> str:
2073        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2063    @property
2064    def quoted(self) -> bool:
2065        return bool(self.args.get("quoted"))
hashable_args: Any
2067    @property
2068    def hashable_args(self) -> t.Any:
2069        return (self.this, self.quoted)
output_name: str
2071    @property
2072    def output_name(self) -> str:
2073        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):
2077class Opclass(Expression):
2078    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2081class Index(Expression):
2082    arg_types = {
2083        "this": False,
2084        "table": False,
2085        "unique": False,
2086        "primary": False,
2087        "amp": False,  # teradata
2088        "params": False,
2089    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2092class IndexParameters(Expression):
2093    arg_types = {
2094        "using": False,
2095        "include": False,
2096        "columns": False,
2097        "with_storage": False,
2098        "partition_by": False,
2099        "tablespace": False,
2100        "where": False,
2101    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
2104class Insert(DDL, DML):
2105    arg_types = {
2106        "hint": False,
2107        "with": False,
2108        "is_function": False,
2109        "this": False,
2110        "expression": False,
2111        "conflict": False,
2112        "returning": False,
2113        "overwrite": False,
2114        "exists": False,
2115        "alternative": False,
2116        "where": False,
2117        "ignore": False,
2118        "by_name": False,
2119        "stored": False,
2120    }
2121
2122    def with_(
2123        self,
2124        alias: ExpOrStr,
2125        as_: ExpOrStr,
2126        recursive: t.Optional[bool] = None,
2127        append: bool = True,
2128        dialect: DialectType = None,
2129        copy: bool = True,
2130        **opts,
2131    ) -> Insert:
2132        """
2133        Append to or set the common table expressions.
2134
2135        Example:
2136            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2137            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2138
2139        Args:
2140            alias: the SQL code string to parse as the table name.
2141                If an `Expression` instance is passed, this is used as-is.
2142            as_: the SQL code string to parse as the table expression.
2143                If an `Expression` instance is passed, it will be used as-is.
2144            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2145            append: if `True`, add to any existing expressions.
2146                Otherwise, this resets the expressions.
2147            dialect: the dialect used to parse the input expression.
2148            copy: if `False`, modify this expression instance in-place.
2149            opts: other options to use to parse the input expressions.
2150
2151        Returns:
2152            The modified expression.
2153        """
2154        return _apply_cte_builder(
2155            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2156        )
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:
2122    def with_(
2123        self,
2124        alias: ExpOrStr,
2125        as_: ExpOrStr,
2126        recursive: t.Optional[bool] = None,
2127        append: bool = True,
2128        dialect: DialectType = None,
2129        copy: bool = True,
2130        **opts,
2131    ) -> Insert:
2132        """
2133        Append to or set the common table expressions.
2134
2135        Example:
2136            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2137            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2138
2139        Args:
2140            alias: the SQL code string to parse as the table name.
2141                If an `Expression` instance is passed, this is used as-is.
2142            as_: the SQL code string to parse as the table expression.
2143                If an `Expression` instance is passed, it will be used as-is.
2144            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2145            append: if `True`, add to any existing expressions.
2146                Otherwise, this resets the expressions.
2147            dialect: the dialect used to parse the input expression.
2148            copy: if `False`, modify this expression instance in-place.
2149            opts: other options to use to parse the input expressions.
2150
2151        Returns:
2152            The modified expression.
2153        """
2154        return _apply_cte_builder(
2155            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2156        )

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):
2159class OnConflict(Expression):
2160    arg_types = {
2161        "duplicate": False,
2162        "expressions": False,
2163        "action": False,
2164        "conflict_keys": False,
2165        "constraint": False,
2166    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2169class Returning(Expression):
2170    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2174class Introducer(Expression):
2175    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2179class National(Expression):
2180    pass
key = 'national'
class LoadData(Expression):
2183class LoadData(Expression):
2184    arg_types = {
2185        "this": True,
2186        "local": False,
2187        "overwrite": False,
2188        "inpath": True,
2189        "partition": False,
2190        "input_format": False,
2191        "serde": False,
2192    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2195class Partition(Expression):
2196    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2199class PartitionRange(Expression):
2200    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2204class PartitionId(Expression):
2205    pass
key = 'partitionid'
class Fetch(Expression):
2208class Fetch(Expression):
2209    arg_types = {
2210        "direction": False,
2211        "count": False,
2212        "percent": False,
2213        "with_ties": False,
2214    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2217class Group(Expression):
2218    arg_types = {
2219        "expressions": False,
2220        "grouping_sets": False,
2221        "cube": False,
2222        "rollup": False,
2223        "totals": False,
2224        "all": False,
2225    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2228class Lambda(Expression):
2229    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2232class Limit(Expression):
2233    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):
2236class Literal(Condition):
2237    arg_types = {"this": True, "is_string": True}
2238
2239    @property
2240    def hashable_args(self) -> t.Any:
2241        return (self.this, self.args.get("is_string"))
2242
2243    @classmethod
2244    def number(cls, number) -> Literal:
2245        return cls(this=str(number), is_string=False)
2246
2247    @classmethod
2248    def string(cls, string) -> Literal:
2249        return cls(this=str(string), is_string=True)
2250
2251    @property
2252    def output_name(self) -> str:
2253        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2239    @property
2240    def hashable_args(self) -> t.Any:
2241        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2243    @classmethod
2244    def number(cls, number) -> Literal:
2245        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2247    @classmethod
2248    def string(cls, string) -> Literal:
2249        return cls(this=str(string), is_string=True)
output_name: str
2251    @property
2252    def output_name(self) -> str:
2253        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):
2256class Join(Expression):
2257    arg_types = {
2258        "this": True,
2259        "on": False,
2260        "side": False,
2261        "kind": False,
2262        "using": False,
2263        "method": False,
2264        "global": False,
2265        "hint": False,
2266        "match_condition": False,  # Snowflake
2267    }
2268
2269    @property
2270    def method(self) -> str:
2271        return self.text("method").upper()
2272
2273    @property
2274    def kind(self) -> str:
2275        return self.text("kind").upper()
2276
2277    @property
2278    def side(self) -> str:
2279        return self.text("side").upper()
2280
2281    @property
2282    def hint(self) -> str:
2283        return self.text("hint").upper()
2284
2285    @property
2286    def alias_or_name(self) -> str:
2287        return self.this.alias_or_name
2288
2289    def on(
2290        self,
2291        *expressions: t.Optional[ExpOrStr],
2292        append: bool = True,
2293        dialect: DialectType = None,
2294        copy: bool = True,
2295        **opts,
2296    ) -> Join:
2297        """
2298        Append to or set the ON expressions.
2299
2300        Example:
2301            >>> import sqlglot
2302            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2303            'JOIN x ON y = 1'
2304
2305        Args:
2306            *expressions: the SQL code strings to parse.
2307                If an `Expression` instance is passed, it will be used as-is.
2308                Multiple expressions are combined with an AND operator.
2309            append: if `True`, AND the new expressions to any existing expression.
2310                Otherwise, this resets the expression.
2311            dialect: the dialect used to parse the input expressions.
2312            copy: if `False`, modify this expression instance in-place.
2313            opts: other options to use to parse the input expressions.
2314
2315        Returns:
2316            The modified Join expression.
2317        """
2318        join = _apply_conjunction_builder(
2319            *expressions,
2320            instance=self,
2321            arg="on",
2322            append=append,
2323            dialect=dialect,
2324            copy=copy,
2325            **opts,
2326        )
2327
2328        if join.kind == "CROSS":
2329            join.set("kind", None)
2330
2331        return join
2332
2333    def using(
2334        self,
2335        *expressions: t.Optional[ExpOrStr],
2336        append: bool = True,
2337        dialect: DialectType = None,
2338        copy: bool = True,
2339        **opts,
2340    ) -> Join:
2341        """
2342        Append to or set the USING expressions.
2343
2344        Example:
2345            >>> import sqlglot
2346            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2347            'JOIN x USING (foo, bla)'
2348
2349        Args:
2350            *expressions: the SQL code strings to parse.
2351                If an `Expression` instance is passed, it will be used as-is.
2352            append: if `True`, concatenate the new expressions to the existing "using" list.
2353                Otherwise, this resets the expression.
2354            dialect: the dialect used to parse the input expressions.
2355            copy: if `False`, modify this expression instance in-place.
2356            opts: other options to use to parse the input expressions.
2357
2358        Returns:
2359            The modified Join expression.
2360        """
2361        join = _apply_list_builder(
2362            *expressions,
2363            instance=self,
2364            arg="using",
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )
2370
2371        if join.kind == "CROSS":
2372            join.set("kind", None)
2373
2374        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
2269    @property
2270    def method(self) -> str:
2271        return self.text("method").upper()
kind: str
2273    @property
2274    def kind(self) -> str:
2275        return self.text("kind").upper()
side: str
2277    @property
2278    def side(self) -> str:
2279        return self.text("side").upper()
hint: str
2281    @property
2282    def hint(self) -> str:
2283        return self.text("hint").upper()
alias_or_name: str
2285    @property
2286    def alias_or_name(self) -> str:
2287        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:
2289    def on(
2290        self,
2291        *expressions: t.Optional[ExpOrStr],
2292        append: bool = True,
2293        dialect: DialectType = None,
2294        copy: bool = True,
2295        **opts,
2296    ) -> Join:
2297        """
2298        Append to or set the ON expressions.
2299
2300        Example:
2301            >>> import sqlglot
2302            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2303            'JOIN x ON y = 1'
2304
2305        Args:
2306            *expressions: the SQL code strings to parse.
2307                If an `Expression` instance is passed, it will be used as-is.
2308                Multiple expressions are combined with an AND operator.
2309            append: if `True`, AND the new expressions to any existing expression.
2310                Otherwise, this resets the expression.
2311            dialect: the dialect used to parse the input expressions.
2312            copy: if `False`, modify this expression instance in-place.
2313            opts: other options to use to parse the input expressions.
2314
2315        Returns:
2316            The modified Join expression.
2317        """
2318        join = _apply_conjunction_builder(
2319            *expressions,
2320            instance=self,
2321            arg="on",
2322            append=append,
2323            dialect=dialect,
2324            copy=copy,
2325            **opts,
2326        )
2327
2328        if join.kind == "CROSS":
2329            join.set("kind", None)
2330
2331        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:
2333    def using(
2334        self,
2335        *expressions: t.Optional[ExpOrStr],
2336        append: bool = True,
2337        dialect: DialectType = None,
2338        copy: bool = True,
2339        **opts,
2340    ) -> Join:
2341        """
2342        Append to or set the USING expressions.
2343
2344        Example:
2345            >>> import sqlglot
2346            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2347            'JOIN x USING (foo, bla)'
2348
2349        Args:
2350            *expressions: the SQL code strings to parse.
2351                If an `Expression` instance is passed, it will be used as-is.
2352            append: if `True`, concatenate the new expressions to the existing "using" list.
2353                Otherwise, this resets the expression.
2354            dialect: the dialect used to parse the input expressions.
2355            copy: if `False`, modify this expression instance in-place.
2356            opts: other options to use to parse the input expressions.
2357
2358        Returns:
2359            The modified Join expression.
2360        """
2361        join = _apply_list_builder(
2362            *expressions,
2363            instance=self,
2364            arg="using",
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )
2370
2371        if join.kind == "CROSS":
2372            join.set("kind", None)
2373
2374        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):
2377class Lateral(UDTF):
2378    arg_types = {
2379        "this": True,
2380        "view": False,
2381        "outer": False,
2382        "alias": False,
2383        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2384    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2387class MatchRecognizeMeasure(Expression):
2388    arg_types = {
2389        "this": True,
2390        "window_frame": False,
2391    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2394class MatchRecognize(Expression):
2395    arg_types = {
2396        "partition_by": False,
2397        "order": False,
2398        "measures": False,
2399        "rows": False,
2400        "after": False,
2401        "pattern": False,
2402        "define": False,
2403        "alias": False,
2404    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2409class Final(Expression):
2410    pass
key = 'final'
class Offset(Expression):
2413class Offset(Expression):
2414    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2417class Order(Expression):
2418    arg_types = {
2419        "this": False,
2420        "expressions": True,
2421        "interpolate": False,
2422        "siblings": False,
2423    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2427class WithFill(Expression):
2428    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2433class Cluster(Order):
2434    pass
key = 'cluster'
class Distribute(Order):
2437class Distribute(Order):
2438    pass
key = 'distribute'
class Sort(Order):
2441class Sort(Order):
2442    pass
key = 'sort'
class Ordered(Expression):
2445class Ordered(Expression):
2446    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):
2449class Property(Expression):
2450    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2453class AllowedValuesProperty(Expression):
2454    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2457class AlgorithmProperty(Property):
2458    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2461class AutoIncrementProperty(Property):
2462    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2466class AutoRefreshProperty(Property):
2467    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2470class BackupProperty(Property):
2471    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2474class BlockCompressionProperty(Property):
2475    arg_types = {
2476        "autotemp": False,
2477        "always": False,
2478        "default": False,
2479        "manual": False,
2480        "never": False,
2481    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2484class CharacterSetProperty(Property):
2485    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2488class ChecksumProperty(Property):
2489    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2492class CollateProperty(Property):
2493    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2496class CopyGrantsProperty(Property):
2497    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2500class DataBlocksizeProperty(Property):
2501    arg_types = {
2502        "size": False,
2503        "units": False,
2504        "minimum": False,
2505        "maximum": False,
2506        "default": False,
2507    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2510class DefinerProperty(Property):
2511    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2514class DistKeyProperty(Property):
2515    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2518class DistStyleProperty(Property):
2519    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2522class EngineProperty(Property):
2523    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2526class HeapProperty(Property):
2527    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2530class ToTableProperty(Property):
2531    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2534class ExecuteAsProperty(Property):
2535    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2538class ExternalProperty(Property):
2539    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2542class FallbackProperty(Property):
2543    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2546class FileFormatProperty(Property):
2547    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2550class FreespaceProperty(Property):
2551    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2554class GlobalProperty(Property):
2555    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2558class IcebergProperty(Property):
2559    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2562class InheritsProperty(Property):
2563    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2566class InputModelProperty(Property):
2567    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2570class OutputModelProperty(Property):
2571    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2574class IsolatedLoadingProperty(Property):
2575    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2578class JournalProperty(Property):
2579    arg_types = {
2580        "no": False,
2581        "dual": False,
2582        "before": False,
2583        "local": False,
2584        "after": False,
2585    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2588class LanguageProperty(Property):
2589    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2593class ClusteredByProperty(Property):
2594    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2597class DictProperty(Property):
2598    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2601class DictSubProperty(Property):
2602    pass
key = 'dictsubproperty'
class DictRange(Property):
2605class DictRange(Property):
2606    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2611class OnCluster(Property):
2612    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2615class LikeProperty(Property):
2616    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2619class LocationProperty(Property):
2620    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2623class LockProperty(Property):
2624    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2627class LockingProperty(Property):
2628    arg_types = {
2629        "this": False,
2630        "kind": True,
2631        "for_or_in": False,
2632        "lock_type": True,
2633        "override": False,
2634    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2637class LogProperty(Property):
2638    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2641class MaterializedProperty(Property):
2642    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2645class MergeBlockRatioProperty(Property):
2646    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):
2649class NoPrimaryIndexProperty(Property):
2650    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2653class OnProperty(Property):
2654    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2657class OnCommitProperty(Property):
2658    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2661class PartitionedByProperty(Property):
2662    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2666class PartitionBoundSpec(Expression):
2667    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2668    arg_types = {
2669        "this": False,
2670        "expression": False,
2671        "from_expressions": False,
2672        "to_expressions": False,
2673    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2676class PartitionedOfProperty(Property):
2677    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2678    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2681class RemoteWithConnectionModelProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2685class ReturnsProperty(Property):
2686    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2689class RowFormatProperty(Property):
2690    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2693class RowFormatDelimitedProperty(Property):
2694    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2695    arg_types = {
2696        "fields": False,
2697        "escaped": False,
2698        "collection_items": False,
2699        "map_keys": False,
2700        "lines": False,
2701        "null": False,
2702        "serde": False,
2703    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2706class RowFormatSerdeProperty(Property):
2707    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2711class QueryTransform(Expression):
2712    arg_types = {
2713        "expressions": True,
2714        "command_script": True,
2715        "schema": False,
2716        "row_format_before": False,
2717        "record_writer": False,
2718        "row_format_after": False,
2719        "record_reader": False,
2720    }
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):
2723class SampleProperty(Property):
2724    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2727class SchemaCommentProperty(Property):
2728    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2731class SerdeProperties(Property):
2732    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2735class SetProperty(Property):
2736    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2739class SharingProperty(Property):
2740    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2743class SetConfigProperty(Property):
2744    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2747class SettingsProperty(Property):
2748    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2751class SortKeyProperty(Property):
2752    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2755class SqlReadWriteProperty(Property):
2756    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2759class SqlSecurityProperty(Property):
2760    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2763class StabilityProperty(Property):
2764    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2767class TemporaryProperty(Property):
2768    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2771class TransformModelProperty(Property):
2772    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2775class TransientProperty(Property):
2776    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2779class UnloggedProperty(Property):
2780    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2784class ViewAttributeProperty(Property):
2785    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2788class VolatileProperty(Property):
2789    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2792class WithDataProperty(Property):
2793    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2796class WithJournalTableProperty(Property):
2797    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2800class WithSystemVersioningProperty(Property):
2801    # this -> history table name, expression -> data consistency check
2802    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2805class Properties(Expression):
2806    arg_types = {"expressions": True}
2807
2808    NAME_TO_PROPERTY = {
2809        "ALGORITHM": AlgorithmProperty,
2810        "AUTO_INCREMENT": AutoIncrementProperty,
2811        "CHARACTER SET": CharacterSetProperty,
2812        "CLUSTERED_BY": ClusteredByProperty,
2813        "COLLATE": CollateProperty,
2814        "COMMENT": SchemaCommentProperty,
2815        "DEFINER": DefinerProperty,
2816        "DISTKEY": DistKeyProperty,
2817        "DISTSTYLE": DistStyleProperty,
2818        "ENGINE": EngineProperty,
2819        "EXECUTE AS": ExecuteAsProperty,
2820        "FORMAT": FileFormatProperty,
2821        "LANGUAGE": LanguageProperty,
2822        "LOCATION": LocationProperty,
2823        "LOCK": LockProperty,
2824        "PARTITIONED_BY": PartitionedByProperty,
2825        "RETURNS": ReturnsProperty,
2826        "ROW_FORMAT": RowFormatProperty,
2827        "SORTKEY": SortKeyProperty,
2828    }
2829
2830    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2831
2832    # CREATE property locations
2833    # Form: schema specified
2834    #   create [POST_CREATE]
2835    #     table a [POST_NAME]
2836    #     (b int) [POST_SCHEMA]
2837    #     with ([POST_WITH])
2838    #     index (b) [POST_INDEX]
2839    #
2840    # Form: alias selection
2841    #   create [POST_CREATE]
2842    #     table a [POST_NAME]
2843    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2844    #     index (c) [POST_INDEX]
2845    class Location(AutoName):
2846        POST_CREATE = auto()
2847        POST_NAME = auto()
2848        POST_SCHEMA = auto()
2849        POST_WITH = auto()
2850        POST_ALIAS = auto()
2851        POST_EXPRESSION = auto()
2852        POST_INDEX = auto()
2853        UNSUPPORTED = auto()
2854
2855    @classmethod
2856    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2857        expressions = []
2858        for key, value in properties_dict.items():
2859            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2860            if property_cls:
2861                expressions.append(property_cls(this=convert(value)))
2862            else:
2863                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2864
2865        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:
2855    @classmethod
2856    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2857        expressions = []
2858        for key, value in properties_dict.items():
2859            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2860            if property_cls:
2861                expressions.append(property_cls(this=convert(value)))
2862            else:
2863                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2864
2865        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2845    class Location(AutoName):
2846        POST_CREATE = auto()
2847        POST_NAME = auto()
2848        POST_SCHEMA = auto()
2849        POST_WITH = auto()
2850        POST_ALIAS = auto()
2851        POST_EXPRESSION = auto()
2852        POST_INDEX = auto()
2853        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):
2868class Qualify(Expression):
2869    pass
key = 'qualify'
class InputOutputFormat(Expression):
2872class InputOutputFormat(Expression):
2873    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2877class Return(Expression):
2878    pass
key = 'return'
class Reference(Expression):
2881class Reference(Expression):
2882    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2885class Tuple(Expression):
2886    arg_types = {"expressions": False}
2887
2888    def isin(
2889        self,
2890        *expressions: t.Any,
2891        query: t.Optional[ExpOrStr] = None,
2892        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2893        copy: bool = True,
2894        **opts,
2895    ) -> In:
2896        return In(
2897            this=maybe_copy(self, copy),
2898            expressions=[convert(e, copy=copy) for e in expressions],
2899            query=maybe_parse(query, copy=copy, **opts) if query else None,
2900            unnest=(
2901                Unnest(
2902                    expressions=[
2903                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2904                        for e in ensure_list(unnest)
2905                    ]
2906                )
2907                if unnest
2908                else None
2909            ),
2910        )
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:
2888    def isin(
2889        self,
2890        *expressions: t.Any,
2891        query: t.Optional[ExpOrStr] = None,
2892        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2893        copy: bool = True,
2894        **opts,
2895    ) -> In:
2896        return In(
2897            this=maybe_copy(self, copy),
2898            expressions=[convert(e, copy=copy) for e in expressions],
2899            query=maybe_parse(query, copy=copy, **opts) if query else None,
2900            unnest=(
2901                Unnest(
2902                    expressions=[
2903                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2904                        for e in ensure_list(unnest)
2905                    ]
2906                )
2907                if unnest
2908                else None
2909            ),
2910        )
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):
2941class QueryOption(Expression):
2942    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2946class WithTableHint(Expression):
2947    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2951class IndexTableHint(Expression):
2952    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2956class HistoricalData(Expression):
2957    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2960class Table(Expression):
2961    arg_types = {
2962        "this": False,
2963        "alias": False,
2964        "db": False,
2965        "catalog": False,
2966        "laterals": False,
2967        "joins": False,
2968        "pivots": False,
2969        "hints": False,
2970        "system_time": False,
2971        "version": False,
2972        "format": False,
2973        "pattern": False,
2974        "ordinality": False,
2975        "when": False,
2976        "only": False,
2977        "partition": False,
2978    }
2979
2980    @property
2981    def name(self) -> str:
2982        if isinstance(self.this, Func):
2983            return ""
2984        return self.this.name
2985
2986    @property
2987    def db(self) -> str:
2988        return self.text("db")
2989
2990    @property
2991    def catalog(self) -> str:
2992        return self.text("catalog")
2993
2994    @property
2995    def selects(self) -> t.List[Expression]:
2996        return []
2997
2998    @property
2999    def named_selects(self) -> t.List[str]:
3000        return []
3001
3002    @property
3003    def parts(self) -> t.List[Expression]:
3004        """Return the parts of a table in order catalog, db, table."""
3005        parts: t.List[Expression] = []
3006
3007        for arg in ("catalog", "db", "this"):
3008            part = self.args.get(arg)
3009
3010            if isinstance(part, Dot):
3011                parts.extend(part.flatten())
3012            elif isinstance(part, Expression):
3013                parts.append(part)
3014
3015        return parts
3016
3017    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3018        parts = self.parts
3019        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3020        alias = self.args.get("alias")
3021        if alias:
3022            col = alias_(col, alias.this, copy=copy)
3023        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
2980    @property
2981    def name(self) -> str:
2982        if isinstance(self.this, Func):
2983            return ""
2984        return self.this.name
db: str
2986    @property
2987    def db(self) -> str:
2988        return self.text("db")
catalog: str
2990    @property
2991    def catalog(self) -> str:
2992        return self.text("catalog")
selects: List[Expression]
2994    @property
2995    def selects(self) -> t.List[Expression]:
2996        return []
named_selects: List[str]
2998    @property
2999    def named_selects(self) -> t.List[str]:
3000        return []
parts: List[Expression]
3002    @property
3003    def parts(self) -> t.List[Expression]:
3004        """Return the parts of a table in order catalog, db, table."""
3005        parts: t.List[Expression] = []
3006
3007        for arg in ("catalog", "db", "this"):
3008            part = self.args.get(arg)
3009
3010            if isinstance(part, Dot):
3011                parts.extend(part.flatten())
3012            elif isinstance(part, Expression):
3013                parts.append(part)
3014
3015        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3017    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3018        parts = self.parts
3019        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3020        alias = self.args.get("alias")
3021        if alias:
3022            col = alias_(col, alias.this, copy=copy)
3023        return col
key = 'table'
class Union(Query):
3026class Union(Query):
3027    arg_types = {
3028        "with": False,
3029        "this": True,
3030        "expression": True,
3031        "distinct": False,
3032        "by_name": False,
3033        **QUERY_MODIFIERS,
3034    }
3035
3036    def select(
3037        self,
3038        *expressions: t.Optional[ExpOrStr],
3039        append: bool = True,
3040        dialect: DialectType = None,
3041        copy: bool = True,
3042        **opts,
3043    ) -> Union:
3044        this = maybe_copy(self, copy)
3045        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3046        this.expression.unnest().select(
3047            *expressions, append=append, dialect=dialect, copy=False, **opts
3048        )
3049        return this
3050
3051    @property
3052    def named_selects(self) -> t.List[str]:
3053        return self.this.unnest().named_selects
3054
3055    @property
3056    def is_star(self) -> bool:
3057        return self.this.is_star or self.expression.is_star
3058
3059    @property
3060    def selects(self) -> t.List[Expression]:
3061        return self.this.unnest().selects
3062
3063    @property
3064    def left(self) -> Expression:
3065        return self.this
3066
3067    @property
3068    def right(self) -> Expression:
3069        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:
3036    def select(
3037        self,
3038        *expressions: t.Optional[ExpOrStr],
3039        append: bool = True,
3040        dialect: DialectType = None,
3041        copy: bool = True,
3042        **opts,
3043    ) -> Union:
3044        this = maybe_copy(self, copy)
3045        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3046        this.expression.unnest().select(
3047            *expressions, append=append, dialect=dialect, copy=False, **opts
3048        )
3049        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]
3051    @property
3052    def named_selects(self) -> t.List[str]:
3053        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3055    @property
3056    def is_star(self) -> bool:
3057        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3059    @property
3060    def selects(self) -> t.List[Expression]:
3061        return self.this.unnest().selects

Returns the query's projections.

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

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:
3185    def group_by(
3186        self,
3187        *expressions: t.Optional[ExpOrStr],
3188        append: bool = True,
3189        dialect: DialectType = None,
3190        copy: bool = True,
3191        **opts,
3192    ) -> Select:
3193        """
3194        Set the GROUP BY expression.
3195
3196        Example:
3197            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3198            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3199
3200        Args:
3201            *expressions: the SQL code strings to parse.
3202                If a `Group` instance is passed, this is used as-is.
3203                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3204                If nothing is passed in then a group by is not applied to the expression
3205            append: if `True`, add to any existing expressions.
3206                Otherwise, this flattens all the `Group` expression into a single expression.
3207            dialect: the dialect used to parse the input expression.
3208            copy: if `False`, modify this expression instance in-place.
3209            opts: other options to use to parse the input expressions.
3210
3211        Returns:
3212            The modified Select expression.
3213        """
3214        if not expressions:
3215            return self if not copy else self.copy()
3216
3217        return _apply_child_list_builder(
3218            *expressions,
3219            instance=self,
3220            arg="group",
3221            append=append,
3222            copy=copy,
3223            prefix="GROUP BY",
3224            into=Group,
3225            dialect=dialect,
3226            **opts,
3227        )

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:
3229    def sort_by(
3230        self,
3231        *expressions: t.Optional[ExpOrStr],
3232        append: bool = True,
3233        dialect: DialectType = None,
3234        copy: bool = True,
3235        **opts,
3236    ) -> Select:
3237        """
3238        Set the SORT BY expression.
3239
3240        Example:
3241            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3242            'SELECT x FROM tbl SORT BY x DESC'
3243
3244        Args:
3245            *expressions: the SQL code strings to parse.
3246                If a `Group` instance is passed, this is used as-is.
3247                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3248            append: if `True`, add to any existing expressions.
3249                Otherwise, this flattens all the `Order` expression into a single expression.
3250            dialect: the dialect used to parse the input expression.
3251            copy: if `False`, modify this expression instance in-place.
3252            opts: other options to use to parse the input expressions.
3253
3254        Returns:
3255            The modified Select expression.
3256        """
3257        return _apply_child_list_builder(
3258            *expressions,
3259            instance=self,
3260            arg="sort",
3261            append=append,
3262            copy=copy,
3263            prefix="SORT BY",
3264            into=Sort,
3265            dialect=dialect,
3266            **opts,
3267        )

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:
3269    def cluster_by(
3270        self,
3271        *expressions: t.Optional[ExpOrStr],
3272        append: bool = True,
3273        dialect: DialectType = None,
3274        copy: bool = True,
3275        **opts,
3276    ) -> Select:
3277        """
3278        Set the CLUSTER BY expression.
3279
3280        Example:
3281            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3282            'SELECT x FROM tbl CLUSTER BY x DESC'
3283
3284        Args:
3285            *expressions: the SQL code strings to parse.
3286                If a `Group` instance is passed, this is used as-is.
3287                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3288            append: if `True`, add to any existing expressions.
3289                Otherwise, this flattens all the `Order` expression into a single expression.
3290            dialect: the dialect used to parse the input expression.
3291            copy: if `False`, modify this expression instance in-place.
3292            opts: other options to use to parse the input expressions.
3293
3294        Returns:
3295            The modified Select expression.
3296        """
3297        return _apply_child_list_builder(
3298            *expressions,
3299            instance=self,
3300            arg="cluster",
3301            append=append,
3302            copy=copy,
3303            prefix="CLUSTER BY",
3304            into=Cluster,
3305            dialect=dialect,
3306            **opts,
3307        )

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:
3309    def select(
3310        self,
3311        *expressions: t.Optional[ExpOrStr],
3312        append: bool = True,
3313        dialect: DialectType = None,
3314        copy: bool = True,
3315        **opts,
3316    ) -> Select:
3317        return _apply_list_builder(
3318            *expressions,
3319            instance=self,
3320            arg="expressions",
3321            append=append,
3322            dialect=dialect,
3323            into=Expression,
3324            copy=copy,
3325            **opts,
3326        )

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:
3328    def lateral(
3329        self,
3330        *expressions: t.Optional[ExpOrStr],
3331        append: bool = True,
3332        dialect: DialectType = None,
3333        copy: bool = True,
3334        **opts,
3335    ) -> Select:
3336        """
3337        Append to or set the LATERAL expressions.
3338
3339        Example:
3340            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3341            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3342
3343        Args:
3344            *expressions: the SQL code strings to parse.
3345                If an `Expression` instance is passed, it will be used as-is.
3346            append: if `True`, add to any existing expressions.
3347                Otherwise, this resets the expressions.
3348            dialect: the dialect used to parse the input expressions.
3349            copy: if `False`, modify this expression instance in-place.
3350            opts: other options to use to parse the input expressions.
3351
3352        Returns:
3353            The modified Select expression.
3354        """
3355        return _apply_list_builder(
3356            *expressions,
3357            instance=self,
3358            arg="laterals",
3359            append=append,
3360            into=Lateral,
3361            prefix="LATERAL VIEW",
3362            dialect=dialect,
3363            copy=copy,
3364            **opts,
3365        )

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:
3367    def join(
3368        self,
3369        expression: ExpOrStr,
3370        on: t.Optional[ExpOrStr] = None,
3371        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3372        append: bool = True,
3373        join_type: t.Optional[str] = None,
3374        join_alias: t.Optional[Identifier | str] = None,
3375        dialect: DialectType = None,
3376        copy: bool = True,
3377        **opts,
3378    ) -> Select:
3379        """
3380        Append to or set the JOIN expressions.
3381
3382        Example:
3383            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3384            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3385
3386            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3387            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3388
3389            Use `join_type` to change the type of join:
3390
3391            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3392            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3393
3394        Args:
3395            expression: the SQL code string to parse.
3396                If an `Expression` instance is passed, it will be used as-is.
3397            on: optionally specify the join "on" criteria as a SQL string.
3398                If an `Expression` instance is passed, it will be used as-is.
3399            using: optionally specify the join "using" criteria as a SQL string.
3400                If an `Expression` instance is passed, it will be used as-is.
3401            append: if `True`, add to any existing expressions.
3402                Otherwise, this resets the expressions.
3403            join_type: if set, alter the parsed join type.
3404            join_alias: an optional alias for the joined source.
3405            dialect: the dialect used to parse the input expressions.
3406            copy: if `False`, modify this expression instance in-place.
3407            opts: other options to use to parse the input expressions.
3408
3409        Returns:
3410            Select: the modified expression.
3411        """
3412        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3413
3414        try:
3415            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3416        except ParseError:
3417            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3418
3419        join = expression if isinstance(expression, Join) else Join(this=expression)
3420
3421        if isinstance(join.this, Select):
3422            join.this.replace(join.this.subquery())
3423
3424        if join_type:
3425            method: t.Optional[Token]
3426            side: t.Optional[Token]
3427            kind: t.Optional[Token]
3428
3429            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3430
3431            if method:
3432                join.set("method", method.text)
3433            if side:
3434                join.set("side", side.text)
3435            if kind:
3436                join.set("kind", kind.text)
3437
3438        if on:
3439            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3440            join.set("on", on)
3441
3442        if using:
3443            join = _apply_list_builder(
3444                *ensure_list(using),
3445                instance=join,
3446                arg="using",
3447                append=append,
3448                copy=copy,
3449                into=Identifier,
3450                **opts,
3451            )
3452
3453        if join_alias:
3454            join.set("this", alias_(join.this, join_alias, table=True))
3455
3456        return _apply_list_builder(
3457            join,
3458            instance=self,
3459            arg="joins",
3460            append=append,
3461            copy=copy,
3462            **opts,
3463        )

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:
3465    def where(
3466        self,
3467        *expressions: t.Optional[ExpOrStr],
3468        append: bool = True,
3469        dialect: DialectType = None,
3470        copy: bool = True,
3471        **opts,
3472    ) -> Select:
3473        """
3474        Append to or set the WHERE expressions.
3475
3476        Example:
3477            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3478            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3479
3480        Args:
3481            *expressions: the SQL code strings to parse.
3482                If an `Expression` instance is passed, it will be used as-is.
3483                Multiple expressions are combined with an AND operator.
3484            append: if `True`, AND the new expressions to any existing expression.
3485                Otherwise, this resets the expression.
3486            dialect: the dialect used to parse the input expressions.
3487            copy: if `False`, modify this expression instance in-place.
3488            opts: other options to use to parse the input expressions.
3489
3490        Returns:
3491            Select: the modified expression.
3492        """
3493        return _apply_conjunction_builder(
3494            *expressions,
3495            instance=self,
3496            arg="where",
3497            append=append,
3498            into=Where,
3499            dialect=dialect,
3500            copy=copy,
3501            **opts,
3502        )

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

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:
3543    def window(
3544        self,
3545        *expressions: t.Optional[ExpOrStr],
3546        append: bool = True,
3547        dialect: DialectType = None,
3548        copy: bool = True,
3549        **opts,
3550    ) -> Select:
3551        return _apply_list_builder(
3552            *expressions,
3553            instance=self,
3554            arg="windows",
3555            append=append,
3556            into=Window,
3557            dialect=dialect,
3558            copy=copy,
3559            **opts,
3560        )
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:
3562    def qualify(
3563        self,
3564        *expressions: t.Optional[ExpOrStr],
3565        append: bool = True,
3566        dialect: DialectType = None,
3567        copy: bool = True,
3568        **opts,
3569    ) -> Select:
3570        return _apply_conjunction_builder(
3571            *expressions,
3572            instance=self,
3573            arg="qualify",
3574            append=append,
3575            into=Qualify,
3576            dialect=dialect,
3577            copy=copy,
3578            **opts,
3579        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3581    def distinct(
3582        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3583    ) -> Select:
3584        """
3585        Set the OFFSET expression.
3586
3587        Example:
3588            >>> Select().from_("tbl").select("x").distinct().sql()
3589            'SELECT DISTINCT x FROM tbl'
3590
3591        Args:
3592            ons: the expressions to distinct on
3593            distinct: whether the Select should be distinct
3594            copy: if `False`, modify this expression instance in-place.
3595
3596        Returns:
3597            Select: the modified expression.
3598        """
3599        instance = maybe_copy(self, copy)
3600        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3601        instance.set("distinct", Distinct(on=on) if distinct else None)
3602        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:
3604    def ctas(
3605        self,
3606        table: ExpOrStr,
3607        properties: t.Optional[t.Dict] = None,
3608        dialect: DialectType = None,
3609        copy: bool = True,
3610        **opts,
3611    ) -> Create:
3612        """
3613        Convert this expression to a CREATE TABLE AS statement.
3614
3615        Example:
3616            >>> Select().select("*").from_("tbl").ctas("x").sql()
3617            'CREATE TABLE x AS SELECT * FROM tbl'
3618
3619        Args:
3620            table: the SQL code string to parse as the table name.
3621                If another `Expression` instance is passed, it will be used as-is.
3622            properties: an optional mapping of table properties
3623            dialect: the dialect used to parse the input table.
3624            copy: if `False`, modify this expression instance in-place.
3625            opts: other options to use to parse the input table.
3626
3627        Returns:
3628            The new Create expression.
3629        """
3630        instance = maybe_copy(self, copy)
3631        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3632
3633        properties_expression = None
3634        if properties:
3635            properties_expression = Properties.from_dict(properties)
3636
3637        return Create(
3638            this=table_expression,
3639            kind="TABLE",
3640            expression=instance,
3641            properties=properties_expression,
3642        )

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:
3644    def lock(self, update: bool = True, copy: bool = True) -> Select:
3645        """
3646        Set the locking read mode for this expression.
3647
3648        Examples:
3649            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3650            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3651
3652            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3653            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3654
3655        Args:
3656            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3657            copy: if `False`, modify this expression instance in-place.
3658
3659        Returns:
3660            The modified expression.
3661        """
3662        inst = maybe_copy(self, copy)
3663        inst.set("locks", [Lock(update=update)])
3664
3665        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:
3667    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3668        """
3669        Set hints for this expression.
3670
3671        Examples:
3672            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3673            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3674
3675        Args:
3676            hints: The SQL code strings to parse as the hints.
3677                If an `Expression` instance is passed, it will be used as-is.
3678            dialect: The dialect used to parse the hints.
3679            copy: If `False`, modify this expression instance in-place.
3680
3681        Returns:
3682            The modified expression.
3683        """
3684        inst = maybe_copy(self, copy)
3685        inst.set(
3686            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3687        )
3688
3689        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]
3691    @property
3692    def named_selects(self) -> t.List[str]:
3693        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
3695    @property
3696    def is_star(self) -> bool:
3697        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3699    @property
3700    def selects(self) -> t.List[Expression]:
3701        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3707class Subquery(DerivedTable, Query):
3708    arg_types = {
3709        "this": True,
3710        "alias": False,
3711        "with": False,
3712        **QUERY_MODIFIERS,
3713    }
3714
3715    def unnest(self):
3716        """Returns the first non subquery."""
3717        expression = self
3718        while isinstance(expression, Subquery):
3719            expression = expression.this
3720        return expression
3721
3722    def unwrap(self) -> Subquery:
3723        expression = self
3724        while expression.same_parent and expression.is_wrapper:
3725            expression = t.cast(Subquery, expression.parent)
3726        return expression
3727
3728    def select(
3729        self,
3730        *expressions: t.Optional[ExpOrStr],
3731        append: bool = True,
3732        dialect: DialectType = None,
3733        copy: bool = True,
3734        **opts,
3735    ) -> Subquery:
3736        this = maybe_copy(self, copy)
3737        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3738        return this
3739
3740    @property
3741    def is_wrapper(self) -> bool:
3742        """
3743        Whether this Subquery acts as a simple wrapper around another expression.
3744
3745        SELECT * FROM (((SELECT * FROM t)))
3746                      ^
3747                      This corresponds to a "wrapper" Subquery node
3748        """
3749        return all(v is None for k, v in self.args.items() if k != "this")
3750
3751    @property
3752    def is_star(self) -> bool:
3753        return self.this.is_star
3754
3755    @property
3756    def output_name(self) -> str:
3757        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):
3715    def unnest(self):
3716        """Returns the first non subquery."""
3717        expression = self
3718        while isinstance(expression, Subquery):
3719            expression = expression.this
3720        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3722    def unwrap(self) -> Subquery:
3723        expression = self
3724        while expression.same_parent and expression.is_wrapper:
3725            expression = t.cast(Subquery, expression.parent)
3726        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:
3728    def select(
3729        self,
3730        *expressions: t.Optional[ExpOrStr],
3731        append: bool = True,
3732        dialect: DialectType = None,
3733        copy: bool = True,
3734        **opts,
3735    ) -> Subquery:
3736        this = maybe_copy(self, copy)
3737        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3738        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
3740    @property
3741    def is_wrapper(self) -> bool:
3742        """
3743        Whether this Subquery acts as a simple wrapper around another expression.
3744
3745        SELECT * FROM (((SELECT * FROM t)))
3746                      ^
3747                      This corresponds to a "wrapper" Subquery node
3748        """
3749        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
3751    @property
3752    def is_star(self) -> bool:
3753        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3755    @property
3756    def output_name(self) -> str:
3757        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):
3760class TableSample(Expression):
3761    arg_types = {
3762        "this": False,
3763        "expressions": False,
3764        "method": False,
3765        "bucket_numerator": False,
3766        "bucket_denominator": False,
3767        "bucket_field": False,
3768        "percent": False,
3769        "rows": False,
3770        "size": False,
3771        "seed": False,
3772    }
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):
3775class Tag(Expression):
3776    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3777
3778    arg_types = {
3779        "this": False,
3780        "prefix": False,
3781        "postfix": False,
3782    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3787class Pivot(Expression):
3788    arg_types = {
3789        "this": False,
3790        "alias": False,
3791        "expressions": False,
3792        "field": False,
3793        "unpivot": False,
3794        "using": False,
3795        "group": False,
3796        "columns": False,
3797        "include_nulls": False,
3798    }
3799
3800    @property
3801    def unpivot(self) -> bool:
3802        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
3800    @property
3801    def unpivot(self) -> bool:
3802        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3805class Window(Condition):
3806    arg_types = {
3807        "this": True,
3808        "partition_by": False,
3809        "order": False,
3810        "spec": False,
3811        "alias": False,
3812        "over": False,
3813        "first": False,
3814    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3817class WindowSpec(Expression):
3818    arg_types = {
3819        "kind": False,
3820        "start": False,
3821        "start_side": False,
3822        "end": False,
3823        "end_side": False,
3824    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3827class PreWhere(Expression):
3828    pass
key = 'prewhere'
class Where(Expression):
3831class Where(Expression):
3832    pass
key = 'where'
class Star(Expression):
3835class Star(Expression):
3836    arg_types = {"except": False, "replace": False, "rename": False}
3837
3838    @property
3839    def name(self) -> str:
3840        return "*"
3841
3842    @property
3843    def output_name(self) -> str:
3844        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3838    @property
3839    def name(self) -> str:
3840        return "*"
output_name: str
3842    @property
3843    def output_name(self) -> str:
3844        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):
3847class Parameter(Condition):
3848    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3851class SessionParameter(Condition):
3852    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3855class Placeholder(Condition):
3856    arg_types = {"this": False, "kind": False}
3857
3858    @property
3859    def name(self) -> str:
3860        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3858    @property
3859    def name(self) -> str:
3860        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3863class Null(Condition):
3864    arg_types: t.Dict[str, t.Any] = {}
3865
3866    @property
3867    def name(self) -> str:
3868        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3866    @property
3867    def name(self) -> str:
3868        return "NULL"
key = 'null'
class Boolean(Condition):
3871class Boolean(Condition):
3872    pass
key = 'boolean'
class DataTypeParam(Expression):
3875class DataTypeParam(Expression):
3876    arg_types = {"this": True, "expression": False}
3877
3878    @property
3879    def name(self) -> str:
3880        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3878    @property
3879    def name(self) -> str:
3880        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3883class DataType(Expression):
3884    arg_types = {
3885        "this": True,
3886        "expressions": False,
3887        "nested": False,
3888        "values": False,
3889        "prefix": False,
3890        "kind": False,
3891    }
3892
3893    class Type(AutoName):
3894        ARRAY = auto()
3895        AGGREGATEFUNCTION = auto()
3896        SIMPLEAGGREGATEFUNCTION = auto()
3897        BIGDECIMAL = auto()
3898        BIGINT = auto()
3899        BIGSERIAL = auto()
3900        BINARY = auto()
3901        BIT = auto()
3902        BOOLEAN = auto()
3903        BPCHAR = auto()
3904        CHAR = auto()
3905        DATE = auto()
3906        DATE32 = auto()
3907        DATEMULTIRANGE = auto()
3908        DATERANGE = auto()
3909        DATETIME = auto()
3910        DATETIME64 = auto()
3911        DECIMAL = auto()
3912        DOUBLE = auto()
3913        ENUM = auto()
3914        ENUM8 = auto()
3915        ENUM16 = auto()
3916        FIXEDSTRING = auto()
3917        FLOAT = auto()
3918        GEOGRAPHY = auto()
3919        GEOMETRY = auto()
3920        HLLSKETCH = auto()
3921        HSTORE = auto()
3922        IMAGE = auto()
3923        INET = auto()
3924        INT = auto()
3925        INT128 = auto()
3926        INT256 = auto()
3927        INT4MULTIRANGE = auto()
3928        INT4RANGE = auto()
3929        INT8MULTIRANGE = auto()
3930        INT8RANGE = auto()
3931        INTERVAL = auto()
3932        IPADDRESS = auto()
3933        IPPREFIX = auto()
3934        IPV4 = auto()
3935        IPV6 = auto()
3936        JSON = auto()
3937        JSONB = auto()
3938        LONGBLOB = auto()
3939        LONGTEXT = auto()
3940        LOWCARDINALITY = auto()
3941        MAP = auto()
3942        MEDIUMBLOB = auto()
3943        MEDIUMINT = auto()
3944        MEDIUMTEXT = auto()
3945        MONEY = auto()
3946        NAME = auto()
3947        NCHAR = auto()
3948        NESTED = auto()
3949        NULL = auto()
3950        NULLABLE = auto()
3951        NUMMULTIRANGE = auto()
3952        NUMRANGE = auto()
3953        NVARCHAR = auto()
3954        OBJECT = auto()
3955        ROWVERSION = auto()
3956        SERIAL = auto()
3957        SET = auto()
3958        SMALLINT = auto()
3959        SMALLMONEY = auto()
3960        SMALLSERIAL = auto()
3961        STRUCT = auto()
3962        SUPER = auto()
3963        TEXT = auto()
3964        TINYBLOB = auto()
3965        TINYTEXT = auto()
3966        TIME = auto()
3967        TIMETZ = auto()
3968        TIMESTAMP = auto()
3969        TIMESTAMPNTZ = auto()
3970        TIMESTAMPLTZ = auto()
3971        TIMESTAMPTZ = auto()
3972        TIMESTAMP_S = auto()
3973        TIMESTAMP_MS = auto()
3974        TIMESTAMP_NS = auto()
3975        TINYINT = auto()
3976        TSMULTIRANGE = auto()
3977        TSRANGE = auto()
3978        TSTZMULTIRANGE = auto()
3979        TSTZRANGE = auto()
3980        UBIGINT = auto()
3981        UINT = auto()
3982        UINT128 = auto()
3983        UINT256 = auto()
3984        UMEDIUMINT = auto()
3985        UDECIMAL = auto()
3986        UNIQUEIDENTIFIER = auto()
3987        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3988        USERDEFINED = "USER-DEFINED"
3989        USMALLINT = auto()
3990        UTINYINT = auto()
3991        UUID = auto()
3992        VARBINARY = auto()
3993        VARCHAR = auto()
3994        VARIANT = auto()
3995        XML = auto()
3996        YEAR = auto()
3997        TDIGEST = auto()
3998
3999    STRUCT_TYPES = {
4000        Type.NESTED,
4001        Type.OBJECT,
4002        Type.STRUCT,
4003    }
4004
4005    NESTED_TYPES = {
4006        *STRUCT_TYPES,
4007        Type.ARRAY,
4008        Type.MAP,
4009    }
4010
4011    TEXT_TYPES = {
4012        Type.CHAR,
4013        Type.NCHAR,
4014        Type.NVARCHAR,
4015        Type.TEXT,
4016        Type.VARCHAR,
4017        Type.NAME,
4018    }
4019
4020    SIGNED_INTEGER_TYPES = {
4021        Type.BIGINT,
4022        Type.INT,
4023        Type.INT128,
4024        Type.INT256,
4025        Type.MEDIUMINT,
4026        Type.SMALLINT,
4027        Type.TINYINT,
4028    }
4029
4030    UNSIGNED_INTEGER_TYPES = {
4031        Type.UBIGINT,
4032        Type.UINT,
4033        Type.UINT128,
4034        Type.UINT256,
4035        Type.UMEDIUMINT,
4036        Type.USMALLINT,
4037        Type.UTINYINT,
4038    }
4039
4040    INTEGER_TYPES = {
4041        *SIGNED_INTEGER_TYPES,
4042        *UNSIGNED_INTEGER_TYPES,
4043        Type.BIT,
4044    }
4045
4046    FLOAT_TYPES = {
4047        Type.DOUBLE,
4048        Type.FLOAT,
4049    }
4050
4051    REAL_TYPES = {
4052        *FLOAT_TYPES,
4053        Type.BIGDECIMAL,
4054        Type.DECIMAL,
4055        Type.MONEY,
4056        Type.SMALLMONEY,
4057        Type.UDECIMAL,
4058    }
4059
4060    NUMERIC_TYPES = {
4061        *INTEGER_TYPES,
4062        *REAL_TYPES,
4063    }
4064
4065    TEMPORAL_TYPES = {
4066        Type.DATE,
4067        Type.DATE32,
4068        Type.DATETIME,
4069        Type.DATETIME64,
4070        Type.TIME,
4071        Type.TIMESTAMP,
4072        Type.TIMESTAMPNTZ,
4073        Type.TIMESTAMPLTZ,
4074        Type.TIMESTAMPTZ,
4075        Type.TIMESTAMP_MS,
4076        Type.TIMESTAMP_NS,
4077        Type.TIMESTAMP_S,
4078        Type.TIMETZ,
4079    }
4080
4081    @classmethod
4082    def build(
4083        cls,
4084        dtype: DATA_TYPE,
4085        dialect: DialectType = None,
4086        udt: bool = False,
4087        copy: bool = True,
4088        **kwargs,
4089    ) -> DataType:
4090        """
4091        Constructs a DataType object.
4092
4093        Args:
4094            dtype: the data type of interest.
4095            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4096            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4097                DataType, thus creating a user-defined type.
4098            copy: whether to copy the data type.
4099            kwargs: additional arguments to pass in the constructor of DataType.
4100
4101        Returns:
4102            The constructed DataType object.
4103        """
4104        from sqlglot import parse_one
4105
4106        if isinstance(dtype, str):
4107            if dtype.upper() == "UNKNOWN":
4108                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4109
4110            try:
4111                data_type_exp = parse_one(
4112                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4113                )
4114            except ParseError:
4115                if udt:
4116                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4117                raise
4118        elif isinstance(dtype, DataType.Type):
4119            data_type_exp = DataType(this=dtype)
4120        elif isinstance(dtype, DataType):
4121            return maybe_copy(dtype, copy)
4122        else:
4123            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4124
4125        return DataType(**{**data_type_exp.args, **kwargs})
4126
4127    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4128        """
4129        Checks whether this DataType matches one of the provided data types. Nested types or precision
4130        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4131
4132        Args:
4133            dtypes: the data types to compare this DataType to.
4134
4135        Returns:
4136            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4137        """
4138        for dtype in dtypes:
4139            other = DataType.build(dtype, copy=False, udt=True)
4140
4141            if (
4142                other.expressions
4143                or self.this == DataType.Type.USERDEFINED
4144                or other.this == DataType.Type.USERDEFINED
4145            ):
4146                matches = self == other
4147            else:
4148                matches = self.this == other.this
4149
4150            if matches:
4151                return True
4152        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.NESTED: 'NESTED'>, <Type.ARRAY: 'ARRAY'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>}
INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT256: 'UINT256'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.BIT: 'BIT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGINT: 'BIGINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.DECIMAL: 'DECIMAL'>, <Type.USMALLINT: 'USMALLINT'>, <Type.FLOAT: 'FLOAT'>, <Type.TINYINT: 'TINYINT'>, <Type.MONEY: 'MONEY'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UTINYINT: 'UTINYINT'>, <Type.BIT: 'BIT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME: 'DATETIME'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATE: 'DATE'>}
@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:
4081    @classmethod
4082    def build(
4083        cls,
4084        dtype: DATA_TYPE,
4085        dialect: DialectType = None,
4086        udt: bool = False,
4087        copy: bool = True,
4088        **kwargs,
4089    ) -> DataType:
4090        """
4091        Constructs a DataType object.
4092
4093        Args:
4094            dtype: the data type of interest.
4095            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4096            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4097                DataType, thus creating a user-defined type.
4098            copy: whether to copy the data type.
4099            kwargs: additional arguments to pass in the constructor of DataType.
4100
4101        Returns:
4102            The constructed DataType object.
4103        """
4104        from sqlglot import parse_one
4105
4106        if isinstance(dtype, str):
4107            if dtype.upper() == "UNKNOWN":
4108                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4109
4110            try:
4111                data_type_exp = parse_one(
4112                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4113                )
4114            except ParseError:
4115                if udt:
4116                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4117                raise
4118        elif isinstance(dtype, DataType.Type):
4119            data_type_exp = DataType(this=dtype)
4120        elif isinstance(dtype, DataType):
4121            return maybe_copy(dtype, copy)
4122        else:
4123            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4124
4125        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:
4127    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4128        """
4129        Checks whether this DataType matches one of the provided data types. Nested types or precision
4130        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4131
4132        Args:
4133            dtypes: the data types to compare this DataType to.
4134
4135        Returns:
4136            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4137        """
4138        for dtype in dtypes:
4139            other = DataType.build(dtype, copy=False, udt=True)
4140
4141            if (
4142                other.expressions
4143                or self.this == DataType.Type.USERDEFINED
4144                or other.this == DataType.Type.USERDEFINED
4145            ):
4146                matches = self == other
4147            else:
4148                matches = self.this == other.this
4149
4150            if matches:
4151                return True
4152        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):
3893    class Type(AutoName):
3894        ARRAY = auto()
3895        AGGREGATEFUNCTION = auto()
3896        SIMPLEAGGREGATEFUNCTION = auto()
3897        BIGDECIMAL = auto()
3898        BIGINT = auto()
3899        BIGSERIAL = auto()
3900        BINARY = auto()
3901        BIT = auto()
3902        BOOLEAN = auto()
3903        BPCHAR = auto()
3904        CHAR = auto()
3905        DATE = auto()
3906        DATE32 = auto()
3907        DATEMULTIRANGE = auto()
3908        DATERANGE = auto()
3909        DATETIME = auto()
3910        DATETIME64 = auto()
3911        DECIMAL = auto()
3912        DOUBLE = auto()
3913        ENUM = auto()
3914        ENUM8 = auto()
3915        ENUM16 = auto()
3916        FIXEDSTRING = auto()
3917        FLOAT = auto()
3918        GEOGRAPHY = auto()
3919        GEOMETRY = auto()
3920        HLLSKETCH = auto()
3921        HSTORE = auto()
3922        IMAGE = auto()
3923        INET = auto()
3924        INT = auto()
3925        INT128 = auto()
3926        INT256 = auto()
3927        INT4MULTIRANGE = auto()
3928        INT4RANGE = auto()
3929        INT8MULTIRANGE = auto()
3930        INT8RANGE = auto()
3931        INTERVAL = auto()
3932        IPADDRESS = auto()
3933        IPPREFIX = auto()
3934        IPV4 = auto()
3935        IPV6 = auto()
3936        JSON = auto()
3937        JSONB = auto()
3938        LONGBLOB = auto()
3939        LONGTEXT = auto()
3940        LOWCARDINALITY = auto()
3941        MAP = auto()
3942        MEDIUMBLOB = auto()
3943        MEDIUMINT = auto()
3944        MEDIUMTEXT = auto()
3945        MONEY = auto()
3946        NAME = auto()
3947        NCHAR = auto()
3948        NESTED = auto()
3949        NULL = auto()
3950        NULLABLE = auto()
3951        NUMMULTIRANGE = auto()
3952        NUMRANGE = auto()
3953        NVARCHAR = auto()
3954        OBJECT = auto()
3955        ROWVERSION = auto()
3956        SERIAL = auto()
3957        SET = auto()
3958        SMALLINT = auto()
3959        SMALLMONEY = auto()
3960        SMALLSERIAL = auto()
3961        STRUCT = auto()
3962        SUPER = auto()
3963        TEXT = auto()
3964        TINYBLOB = auto()
3965        TINYTEXT = auto()
3966        TIME = auto()
3967        TIMETZ = auto()
3968        TIMESTAMP = auto()
3969        TIMESTAMPNTZ = auto()
3970        TIMESTAMPLTZ = auto()
3971        TIMESTAMPTZ = auto()
3972        TIMESTAMP_S = auto()
3973        TIMESTAMP_MS = auto()
3974        TIMESTAMP_NS = auto()
3975        TINYINT = auto()
3976        TSMULTIRANGE = auto()
3977        TSRANGE = auto()
3978        TSTZMULTIRANGE = auto()
3979        TSTZRANGE = auto()
3980        UBIGINT = auto()
3981        UINT = auto()
3982        UINT128 = auto()
3983        UINT256 = auto()
3984        UMEDIUMINT = auto()
3985        UDECIMAL = auto()
3986        UNIQUEIDENTIFIER = auto()
3987        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3988        USERDEFINED = "USER-DEFINED"
3989        USMALLINT = auto()
3990        UTINYINT = auto()
3991        UUID = auto()
3992        VARBINARY = auto()
3993        VARCHAR = auto()
3994        VARIANT = auto()
3995        XML = auto()
3996        YEAR = auto()
3997        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):
4159class PseudoType(DataType):
4160    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4164class ObjectIdentifier(DataType):
4165    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4169class SubqueryPredicate(Predicate):
4170    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4173class All(SubqueryPredicate):
4174    pass
key = 'all'
class Any(SubqueryPredicate):
4177class Any(SubqueryPredicate):
4178    pass
key = 'any'
class Exists(SubqueryPredicate):
4181class Exists(SubqueryPredicate):
4182    pass
key = 'exists'
class Command(Expression):
4187class Command(Expression):
4188    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4191class Transaction(Expression):
4192    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4195class Commit(Expression):
4196    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4199class Rollback(Expression):
4200    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4203class AlterTable(Expression):
4204    arg_types = {
4205        "this": True,
4206        "actions": True,
4207        "exists": False,
4208        "only": False,
4209        "options": False,
4210        "cluster": False,
4211    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4214class AddConstraint(Expression):
4215    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4218class DropPartition(Expression):
4219    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4223class ReplacePartition(Expression):
4224    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4228class Binary(Condition):
4229    arg_types = {"this": True, "expression": True}
4230
4231    @property
4232    def left(self) -> Expression:
4233        return self.this
4234
4235    @property
4236    def right(self) -> Expression:
4237        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4231    @property
4232    def left(self) -> Expression:
4233        return self.this
right: Expression
4235    @property
4236    def right(self) -> Expression:
4237        return self.expression
key = 'binary'
class Add(Binary):
4240class Add(Binary):
4241    pass
key = 'add'
class Connector(Binary):
4244class Connector(Binary):
4245    pass
key = 'connector'
class And(Connector):
4248class And(Connector):
4249    pass
key = 'and'
class Or(Connector):
4252class Or(Connector):
4253    pass
key = 'or'
class BitwiseAnd(Binary):
4256class BitwiseAnd(Binary):
4257    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4260class BitwiseLeftShift(Binary):
4261    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4264class BitwiseOr(Binary):
4265    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4268class BitwiseRightShift(Binary):
4269    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4272class BitwiseXor(Binary):
4273    pass
key = 'bitwisexor'
class Div(Binary):
4276class Div(Binary):
4277    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):
4280class Overlaps(Binary):
4281    pass
key = 'overlaps'
class Dot(Binary):
4284class Dot(Binary):
4285    @property
4286    def is_star(self) -> bool:
4287        return self.expression.is_star
4288
4289    @property
4290    def name(self) -> str:
4291        return self.expression.name
4292
4293    @property
4294    def output_name(self) -> str:
4295        return self.name
4296
4297    @classmethod
4298    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4299        """Build a Dot object with a sequence of expressions."""
4300        if len(expressions) < 2:
4301            raise ValueError("Dot requires >= 2 expressions.")
4302
4303        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4304
4305    @property
4306    def parts(self) -> t.List[Expression]:
4307        """Return the parts of a table / column in order catalog, db, table."""
4308        this, *parts = self.flatten()
4309
4310        parts.reverse()
4311
4312        for arg in COLUMN_PARTS:
4313            part = this.args.get(arg)
4314
4315            if isinstance(part, Expression):
4316                parts.append(part)
4317
4318        parts.reverse()
4319        return parts
is_star: bool
4285    @property
4286    def is_star(self) -> bool:
4287        return self.expression.is_star

Checks whether an expression is a star.

name: str
4289    @property
4290    def name(self) -> str:
4291        return self.expression.name
output_name: str
4293    @property
4294    def output_name(self) -> str:
4295        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:
4297    @classmethod
4298    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4299        """Build a Dot object with a sequence of expressions."""
4300        if len(expressions) < 2:
4301            raise ValueError("Dot requires >= 2 expressions.")
4302
4303        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]
4305    @property
4306    def parts(self) -> t.List[Expression]:
4307        """Return the parts of a table / column in order catalog, db, table."""
4308        this, *parts = self.flatten()
4309
4310        parts.reverse()
4311
4312        for arg in COLUMN_PARTS:
4313            part = this.args.get(arg)
4314
4315            if isinstance(part, Expression):
4316                parts.append(part)
4317
4318        parts.reverse()
4319        return parts

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

key = 'dot'
class DPipe(Binary):
4322class DPipe(Binary):
4323    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4326class EQ(Binary, Predicate):
4327    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4330class NullSafeEQ(Binary, Predicate):
4331    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4334class NullSafeNEQ(Binary, Predicate):
4335    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4339class PropertyEQ(Binary):
4340    pass
key = 'propertyeq'
class Distance(Binary):
4343class Distance(Binary):
4344    pass
key = 'distance'
class Escape(Binary):
4347class Escape(Binary):
4348    pass
key = 'escape'
class Glob(Binary, Predicate):
4351class Glob(Binary, Predicate):
4352    pass
key = 'glob'
class GT(Binary, Predicate):
4355class GT(Binary, Predicate):
4356    pass
key = 'gt'
class GTE(Binary, Predicate):
4359class GTE(Binary, Predicate):
4360    pass
key = 'gte'
class ILike(Binary, Predicate):
4363class ILike(Binary, Predicate):
4364    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4367class ILikeAny(Binary, Predicate):
4368    pass
key = 'ilikeany'
class IntDiv(Binary):
4371class IntDiv(Binary):
4372    pass
key = 'intdiv'
class Is(Binary, Predicate):
4375class Is(Binary, Predicate):
4376    pass
key = 'is'
class Kwarg(Binary):
4379class Kwarg(Binary):
4380    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4383class Like(Binary, Predicate):
4384    pass
key = 'like'
class LikeAny(Binary, Predicate):
4387class LikeAny(Binary, Predicate):
4388    pass
key = 'likeany'
class LT(Binary, Predicate):
4391class LT(Binary, Predicate):
4392    pass
key = 'lt'
class LTE(Binary, Predicate):
4395class LTE(Binary, Predicate):
4396    pass
key = 'lte'
class Mod(Binary):
4399class Mod(Binary):
4400    pass
key = 'mod'
class Mul(Binary):
4403class Mul(Binary):
4404    pass
key = 'mul'
class NEQ(Binary, Predicate):
4407class NEQ(Binary, Predicate):
4408    pass
key = 'neq'
class Operator(Binary):
4412class Operator(Binary):
4413    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4416class SimilarTo(Binary, Predicate):
4417    pass
key = 'similarto'
class Slice(Binary):
4420class Slice(Binary):
4421    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4424class Sub(Binary):
4425    pass
key = 'sub'
class Unary(Condition):
4430class Unary(Condition):
4431    pass
key = 'unary'
class BitwiseNot(Unary):
4434class BitwiseNot(Unary):
4435    pass
key = 'bitwisenot'
class Not(Unary):
4438class Not(Unary):
4439    pass
key = 'not'
class Paren(Unary):
4442class Paren(Unary):
4443    @property
4444    def output_name(self) -> str:
4445        return self.this.name
output_name: str
4443    @property
4444    def output_name(self) -> str:
4445        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):
4448class Neg(Unary):
4449    pass
key = 'neg'
class Alias(Expression):
4452class Alias(Expression):
4453    arg_types = {"this": True, "alias": False}
4454
4455    @property
4456    def output_name(self) -> str:
4457        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4455    @property
4456    def output_name(self) -> str:
4457        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):
4462class PivotAlias(Alias):
4463    pass
key = 'pivotalias'
class Aliases(Expression):
4466class Aliases(Expression):
4467    arg_types = {"this": True, "expressions": True}
4468
4469    @property
4470    def aliases(self):
4471        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4469    @property
4470    def aliases(self):
4471        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4475class AtIndex(Expression):
4476    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4479class AtTimeZone(Expression):
4480    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4483class FromTimeZone(Expression):
4484    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4487class Between(Predicate):
4488    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4491class Bracket(Condition):
4492    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4493    arg_types = {
4494        "this": True,
4495        "expressions": True,
4496        "offset": False,
4497        "safe": False,
4498        "returns_list_for_maps": False,
4499    }
4500
4501    @property
4502    def output_name(self) -> str:
4503        if len(self.expressions) == 1:
4504            return self.expressions[0].output_name
4505
4506        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4501    @property
4502    def output_name(self) -> str:
4503        if len(self.expressions) == 1:
4504            return self.expressions[0].output_name
4505
4506        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):
4509class Distinct(Expression):
4510    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4513class In(Predicate):
4514    arg_types = {
4515        "this": True,
4516        "expressions": False,
4517        "query": False,
4518        "unnest": False,
4519        "field": False,
4520        "is_global": False,
4521    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4525class ForIn(Expression):
4526    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4529class TimeUnit(Expression):
4530    """Automatically converts unit arg into a var."""
4531
4532    arg_types = {"unit": False}
4533
4534    UNABBREVIATED_UNIT_NAME = {
4535        "D": "DAY",
4536        "H": "HOUR",
4537        "M": "MINUTE",
4538        "MS": "MILLISECOND",
4539        "NS": "NANOSECOND",
4540        "Q": "QUARTER",
4541        "S": "SECOND",
4542        "US": "MICROSECOND",
4543        "W": "WEEK",
4544        "Y": "YEAR",
4545    }
4546
4547    VAR_LIKE = (Column, Literal, Var)
4548
4549    def __init__(self, **args):
4550        unit = args.get("unit")
4551        if isinstance(unit, self.VAR_LIKE):
4552            args["unit"] = Var(
4553                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4554            )
4555        elif isinstance(unit, Week):
4556            unit.set("this", Var(this=unit.this.name.upper()))
4557
4558        super().__init__(**args)
4559
4560    @property
4561    def unit(self) -> t.Optional[Var | IntervalSpan]:
4562        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4549    def __init__(self, **args):
4550        unit = args.get("unit")
4551        if isinstance(unit, self.VAR_LIKE):
4552            args["unit"] = Var(
4553                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4554            )
4555        elif isinstance(unit, Week):
4556            unit.set("this", Var(this=unit.this.name.upper()))
4557
4558        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]
4560    @property
4561    def unit(self) -> t.Optional[Var | IntervalSpan]:
4562        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4565class IntervalOp(TimeUnit):
4566    arg_types = {"unit": True, "expression": True}
4567
4568    def interval(self):
4569        return Interval(
4570            this=self.expression.copy(),
4571            unit=self.unit.copy(),
4572        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4568    def interval(self):
4569        return Interval(
4570            this=self.expression.copy(),
4571            unit=self.unit.copy(),
4572        )
key = 'intervalop'
class IntervalSpan(DataType):
4578class IntervalSpan(DataType):
4579    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4582class Interval(TimeUnit):
4583    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4586class IgnoreNulls(Expression):
4587    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4590class RespectNulls(Expression):
4591    pass
key = 'respectnulls'
class HavingMax(Expression):
4595class HavingMax(Expression):
4596    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4600class Func(Condition):
4601    """
4602    The base class for all function expressions.
4603
4604    Attributes:
4605        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4606            treated as a variable length argument and the argument's value will be stored as a list.
4607        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4608            function expression. These values are used to map this node to a name during parsing as
4609            well as to provide the function's name during SQL string generation. By default the SQL
4610            name is set to the expression's class name transformed to snake case.
4611    """
4612
4613    is_var_len_args = False
4614
4615    @classmethod
4616    def from_arg_list(cls, args):
4617        if cls.is_var_len_args:
4618            all_arg_keys = list(cls.arg_types)
4619            # If this function supports variable length argument treat the last argument as such.
4620            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4621            num_non_var = len(non_var_len_arg_keys)
4622
4623            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4624            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4625        else:
4626            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4627
4628        return cls(**args_dict)
4629
4630    @classmethod
4631    def sql_names(cls):
4632        if cls is Func:
4633            raise NotImplementedError(
4634                "SQL name is only supported by concrete function implementations"
4635            )
4636        if "_sql_names" not in cls.__dict__:
4637            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4638        return cls._sql_names
4639
4640    @classmethod
4641    def sql_name(cls):
4642        return cls.sql_names()[0]
4643
4644    @classmethod
4645    def default_parser_mappings(cls):
4646        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):
4615    @classmethod
4616    def from_arg_list(cls, args):
4617        if cls.is_var_len_args:
4618            all_arg_keys = list(cls.arg_types)
4619            # If this function supports variable length argument treat the last argument as such.
4620            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4621            num_non_var = len(non_var_len_arg_keys)
4622
4623            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4624            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4625        else:
4626            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4627
4628        return cls(**args_dict)
@classmethod
def sql_names(cls):
4630    @classmethod
4631    def sql_names(cls):
4632        if cls is Func:
4633            raise NotImplementedError(
4634                "SQL name is only supported by concrete function implementations"
4635            )
4636        if "_sql_names" not in cls.__dict__:
4637            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4638        return cls._sql_names
@classmethod
def sql_name(cls):
4640    @classmethod
4641    def sql_name(cls):
4642        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4644    @classmethod
4645    def default_parser_mappings(cls):
4646        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4649class AggFunc(Func):
4650    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4653class ParameterizedAgg(AggFunc):
4654    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4657class Abs(Func):
4658    pass
key = 'abs'
class ArgMax(AggFunc):
4661class ArgMax(AggFunc):
4662    arg_types = {"this": True, "expression": True, "count": False}
4663    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4666class ArgMin(AggFunc):
4667    arg_types = {"this": True, "expression": True, "count": False}
4668    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4671class ApproxTopK(AggFunc):
4672    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4675class Flatten(Func):
4676    pass
key = 'flatten'
class Transform(Func):
4680class Transform(Func):
4681    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4684class Anonymous(Func):
4685    arg_types = {"this": True, "expressions": False}
4686    is_var_len_args = True
4687
4688    @property
4689    def name(self) -> str:
4690        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
4688    @property
4689    def name(self) -> str:
4690        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4693class AnonymousAggFunc(AggFunc):
4694    arg_types = {"this": True, "expressions": False}
4695    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4699class CombinedAggFunc(AnonymousAggFunc):
4700    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4703class CombinedParameterizedAgg(ParameterizedAgg):
4704    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):
4709class Hll(AggFunc):
4710    arg_types = {"this": True, "expressions": False}
4711    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4714class ApproxDistinct(AggFunc):
4715    arg_types = {"this": True, "accuracy": False}
4716    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4719class Array(Func):
4720    arg_types = {"expressions": False}
4721    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4725class ToArray(Func):
4726    pass
key = 'toarray'
class ToChar(Func):
4731class ToChar(Func):
4732    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4737class ToNumber(Func):
4738    arg_types = {
4739        "this": True,
4740        "format": False,
4741        "nlsparam": False,
4742        "precision": False,
4743        "scale": False,
4744    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4748class Convert(Func):
4749    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4752class GenerateSeries(Func):
4753    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):
4756class ArrayAgg(AggFunc):
4757    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4760class ArrayUniqueAgg(AggFunc):
4761    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4764class ArrayAll(Func):
4765    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4769class ArrayAny(Func):
4770    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4773class ArrayConcat(Func):
4774    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4775    arg_types = {"this": True, "expressions": False}
4776    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4779class ArrayConstructCompact(Func):
4780    arg_types = {"expressions": True}
4781    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4784class ArrayContains(Binary, Func):
4785    pass
key = 'arraycontains'
class ArrayContained(Binary):
4788class ArrayContained(Binary):
4789    pass
key = 'arraycontained'
class ArrayFilter(Func):
4792class ArrayFilter(Func):
4793    arg_types = {"this": True, "expression": True}
4794    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4797class ArrayToString(Func):
4798    arg_types = {"this": True, "expression": True, "null": False}
4799    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4802class ArrayOverlaps(Binary, Func):
4803    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4806class ArraySize(Func):
4807    arg_types = {"this": True, "expression": False}
4808    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4811class ArraySort(Func):
4812    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4815class ArraySum(Func):
4816    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4819class ArrayUnionAgg(AggFunc):
4820    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4823class Avg(AggFunc):
4824    pass
key = 'avg'
class AnyValue(AggFunc):
4827class AnyValue(AggFunc):
4828    pass
key = 'anyvalue'
class Lag(AggFunc):
4831class Lag(AggFunc):
4832    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4835class Lead(AggFunc):
4836    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4841class First(AggFunc):
4842    pass
key = 'first'
class Last(AggFunc):
4845class Last(AggFunc):
4846    pass
key = 'last'
class FirstValue(AggFunc):
4849class FirstValue(AggFunc):
4850    pass
key = 'firstvalue'
class LastValue(AggFunc):
4853class LastValue(AggFunc):
4854    pass
key = 'lastvalue'
class NthValue(AggFunc):
4857class NthValue(AggFunc):
4858    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4861class Case(Func):
4862    arg_types = {"this": False, "ifs": True, "default": False}
4863
4864    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4865        instance = maybe_copy(self, copy)
4866        instance.append(
4867            "ifs",
4868            If(
4869                this=maybe_parse(condition, copy=copy, **opts),
4870                true=maybe_parse(then, copy=copy, **opts),
4871            ),
4872        )
4873        return instance
4874
4875    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4876        instance = maybe_copy(self, copy)
4877        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4878        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:
4864    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4865        instance = maybe_copy(self, copy)
4866        instance.append(
4867            "ifs",
4868            If(
4869                this=maybe_parse(condition, copy=copy, **opts),
4870                true=maybe_parse(then, copy=copy, **opts),
4871            ),
4872        )
4873        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4875    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4876        instance = maybe_copy(self, copy)
4877        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4878        return instance
key = 'case'
class Cast(Func):
4881class Cast(Func):
4882    arg_types = {
4883        "this": True,
4884        "to": True,
4885        "format": False,
4886        "safe": False,
4887        "action": False,
4888    }
4889
4890    @property
4891    def name(self) -> str:
4892        return self.this.name
4893
4894    @property
4895    def to(self) -> DataType:
4896        return self.args["to"]
4897
4898    @property
4899    def output_name(self) -> str:
4900        return self.name
4901
4902    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4903        """
4904        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4905        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4906        array<int> != array<float>.
4907
4908        Args:
4909            dtypes: the data types to compare this Cast's DataType to.
4910
4911        Returns:
4912            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4913        """
4914        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4890    @property
4891    def name(self) -> str:
4892        return self.this.name
to: DataType
4894    @property
4895    def to(self) -> DataType:
4896        return self.args["to"]
output_name: str
4898    @property
4899    def output_name(self) -> str:
4900        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:
4902    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4903        """
4904        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4905        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4906        array<int> != array<float>.
4907
4908        Args:
4909            dtypes: the data types to compare this Cast's DataType to.
4910
4911        Returns:
4912            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4913        """
4914        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):
4917class TryCast(Cast):
4918    pass
key = 'trycast'
class Try(Func):
4921class Try(Func):
4922    pass
key = 'try'
class CastToStrType(Func):
4925class CastToStrType(Func):
4926    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4929class Collate(Binary, Func):
4930    pass
key = 'collate'
class Ceil(Func):
4933class Ceil(Func):
4934    arg_types = {"this": True, "decimals": False}
4935    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4938class Coalesce(Func):
4939    arg_types = {"this": True, "expressions": False}
4940    is_var_len_args = True
4941    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4944class Chr(Func):
4945    arg_types = {"this": True, "charset": False, "expressions": False}
4946    is_var_len_args = True
4947    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4950class Concat(Func):
4951    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4952    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4955class ConcatWs(Concat):
4956    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4960class ConnectByRoot(Func):
4961    pass
key = 'connectbyroot'
class Count(AggFunc):
4964class Count(AggFunc):
4965    arg_types = {"this": False, "expressions": False}
4966    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4969class CountIf(AggFunc):
4970    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4974class Cbrt(Func):
4975    pass
key = 'cbrt'
class CurrentDate(Func):
4978class CurrentDate(Func):
4979    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4982class CurrentDatetime(Func):
4983    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4986class CurrentTime(Func):
4987    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4990class CurrentTimestamp(Func):
4991    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4994class CurrentUser(Func):
4995    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4998class DateAdd(Func, IntervalOp):
4999    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5002class DateSub(Func, IntervalOp):
5003    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5006class DateDiff(Func, TimeUnit):
5007    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5008    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5011class DateTrunc(Func):
5012    arg_types = {"unit": True, "this": True, "zone": False}
5013
5014    def __init__(self, **args):
5015        unit = args.get("unit")
5016        if isinstance(unit, TimeUnit.VAR_LIKE):
5017            args["unit"] = Literal.string(
5018                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5019            )
5020        elif isinstance(unit, Week):
5021            unit.set("this", Literal.string(unit.this.name.upper()))
5022
5023        super().__init__(**args)
5024
5025    @property
5026    def unit(self) -> Expression:
5027        return self.args["unit"]
DateTrunc(**args)
5014    def __init__(self, **args):
5015        unit = args.get("unit")
5016        if isinstance(unit, TimeUnit.VAR_LIKE):
5017            args["unit"] = Literal.string(
5018                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5019            )
5020        elif isinstance(unit, Week):
5021            unit.set("this", Literal.string(unit.this.name.upper()))
5022
5023        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5025    @property
5026    def unit(self) -> Expression:
5027        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
5030class DatetimeAdd(Func, IntervalOp):
5031    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5034class DatetimeSub(Func, IntervalOp):
5035    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5038class DatetimeDiff(Func, TimeUnit):
5039    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5042class DatetimeTrunc(Func, TimeUnit):
5043    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5046class DayOfWeek(Func):
5047    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5050class DayOfMonth(Func):
5051    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5054class DayOfYear(Func):
5055    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5058class ToDays(Func):
5059    pass
key = 'todays'
class WeekOfYear(Func):
5062class WeekOfYear(Func):
5063    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5066class MonthsBetween(Func):
5067    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5070class LastDay(Func, TimeUnit):
5071    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5072    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5075class Extract(Func):
5076    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5079class Timestamp(Func):
5080    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5083class TimestampAdd(Func, TimeUnit):
5084    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5087class TimestampSub(Func, TimeUnit):
5088    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5091class TimestampDiff(Func, TimeUnit):
5092    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5093    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5096class TimestampTrunc(Func, TimeUnit):
5097    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5100class TimeAdd(Func, TimeUnit):
5101    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5104class TimeSub(Func, TimeUnit):
5105    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5108class TimeDiff(Func, TimeUnit):
5109    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5112class TimeTrunc(Func, TimeUnit):
5113    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5116class DateFromParts(Func):
5117    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5118    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5121class TimeFromParts(Func):
5122    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5123    arg_types = {
5124        "hour": True,
5125        "min": True,
5126        "sec": True,
5127        "nano": False,
5128        "fractions": False,
5129        "precision": False,
5130    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5133class DateStrToDate(Func):
5134    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5137class DateToDateStr(Func):
5138    pass
key = 'datetodatestr'
class DateToDi(Func):
5141class DateToDi(Func):
5142    pass
key = 'datetodi'
class Date(Func):
5146class Date(Func):
5147    arg_types = {"this": False, "zone": False, "expressions": False}
5148    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5151class Day(Func):
5152    pass
key = 'day'
class Decode(Func):
5155class Decode(Func):
5156    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5159class DiToDate(Func):
5160    pass
key = 'ditodate'
class Encode(Func):
5163class Encode(Func):
5164    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5167class Exp(Func):
5168    pass
key = 'exp'
class Explode(Func):
5172class Explode(Func):
5173    arg_types = {"this": True, "expressions": False}
5174    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5177class ExplodeOuter(Explode):
5178    pass
key = 'explodeouter'
class Posexplode(Explode):
5181class Posexplode(Explode):
5182    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5185class PosexplodeOuter(Posexplode, ExplodeOuter):
5186    pass
key = 'posexplodeouter'
class Floor(Func):
5189class Floor(Func):
5190    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5193class FromBase64(Func):
5194    pass
key = 'frombase64'
class ToBase64(Func):
5197class ToBase64(Func):
5198    pass
key = 'tobase64'
class GenerateDateArray(Func):
5201class GenerateDateArray(Func):
5202    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5205class Greatest(Func):
5206    arg_types = {"this": True, "expressions": False}
5207    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5210class GroupConcat(AggFunc):
5211    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5214class Hex(Func):
5215    pass
key = 'hex'
class LowerHex(Hex):
5218class LowerHex(Hex):
5219    pass
key = 'lowerhex'
class Xor(Connector, Func):
5222class Xor(Connector, Func):
5223    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5226class If(Func):
5227    arg_types = {"this": True, "true": True, "false": False}
5228    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5231class Nullif(Func):
5232    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5235class Initcap(Func):
5236    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5239class IsNan(Func):
5240    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5243class IsInf(Func):
5244    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5247class JSONPath(Expression):
5248    arg_types = {"expressions": True}
5249
5250    @property
5251    def output_name(self) -> str:
5252        last_segment = self.expressions[-1].this
5253        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5250    @property
5251    def output_name(self) -> str:
5252        last_segment = self.expressions[-1].this
5253        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):
5256class JSONPathPart(Expression):
5257    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5260class JSONPathFilter(JSONPathPart):
5261    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5264class JSONPathKey(JSONPathPart):
5265    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5268class JSONPathRecursive(JSONPathPart):
5269    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5272class JSONPathRoot(JSONPathPart):
5273    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5276class JSONPathScript(JSONPathPart):
5277    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5280class JSONPathSlice(JSONPathPart):
5281    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5284class JSONPathSelector(JSONPathPart):
5285    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5288class JSONPathSubscript(JSONPathPart):
5289    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5292class JSONPathUnion(JSONPathPart):
5293    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5296class JSONPathWildcard(JSONPathPart):
5297    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5300class FormatJson(Expression):
5301    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5304class JSONKeyValue(Expression):
5305    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5308class JSONObject(Func):
5309    arg_types = {
5310        "expressions": False,
5311        "null_handling": False,
5312        "unique_keys": False,
5313        "return_type": False,
5314        "encoding": False,
5315    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5318class JSONObjectAgg(AggFunc):
5319    arg_types = {
5320        "expressions": False,
5321        "null_handling": False,
5322        "unique_keys": False,
5323        "return_type": False,
5324        "encoding": False,
5325    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5329class JSONArray(Func):
5330    arg_types = {
5331        "expressions": True,
5332        "null_handling": False,
5333        "return_type": False,
5334        "strict": False,
5335    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5339class JSONArrayAgg(Func):
5340    arg_types = {
5341        "this": True,
5342        "order": False,
5343        "null_handling": False,
5344        "return_type": False,
5345        "strict": False,
5346    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5351class JSONColumnDef(Expression):
5352    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):
5355class JSONSchema(Expression):
5356    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5360class JSONTable(Func):
5361    arg_types = {
5362        "this": True,
5363        "schema": True,
5364        "path": False,
5365        "error_handling": False,
5366        "empty_handling": False,
5367    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5370class OpenJSONColumnDef(Expression):
5371    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):
5374class OpenJSON(Func):
5375    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5378class JSONBContains(Binary):
5379    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5382class JSONExtract(Binary, Func):
5383    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5384    _sql_names = ["JSON_EXTRACT"]
5385    is_var_len_args = True
5386
5387    @property
5388    def output_name(self) -> str:
5389        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
5387    @property
5388    def output_name(self) -> str:
5389        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):
5392class JSONExtractScalar(Binary, Func):
5393    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5394    _sql_names = ["JSON_EXTRACT_SCALAR"]
5395    is_var_len_args = True
5396
5397    @property
5398    def output_name(self) -> str:
5399        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
5397    @property
5398    def output_name(self) -> str:
5399        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):
5402class JSONBExtract(Binary, Func):
5403    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5406class JSONBExtractScalar(Binary, Func):
5407    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5410class JSONFormat(Func):
5411    arg_types = {"this": False, "options": False}
5412    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5416class JSONArrayContains(Binary, Predicate, Func):
5417    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5420class ParseJSON(Func):
5421    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5422    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5423    arg_types = {"this": True, "expressions": False}
5424    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5427class Least(Func):
5428    arg_types = {"this": True, "expressions": False}
5429    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5432class Left(Func):
5433    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5440class Length(Func):
5441    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5444class Levenshtein(Func):
5445    arg_types = {
5446        "this": True,
5447        "expression": False,
5448        "ins_cost": False,
5449        "del_cost": False,
5450        "sub_cost": False,
5451    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5454class Ln(Func):
5455    pass
key = 'ln'
class Log(Func):
5458class Log(Func):
5459    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5462class LogicalOr(AggFunc):
5463    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5466class LogicalAnd(AggFunc):
5467    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5470class Lower(Func):
5471    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5474class Map(Func):
5475    arg_types = {"keys": False, "values": False}
5476
5477    @property
5478    def keys(self) -> t.List[Expression]:
5479        keys = self.args.get("keys")
5480        return keys.expressions if keys else []
5481
5482    @property
5483    def values(self) -> t.List[Expression]:
5484        values = self.args.get("values")
5485        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5477    @property
5478    def keys(self) -> t.List[Expression]:
5479        keys = self.args.get("keys")
5480        return keys.expressions if keys else []
values: List[Expression]
5482    @property
5483    def values(self) -> t.List[Expression]:
5484        values = self.args.get("values")
5485        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5489class ToMap(Func):
5490    pass
key = 'tomap'
class MapFromEntries(Func):
5493class MapFromEntries(Func):
5494    pass
key = 'mapfromentries'
class StarMap(Func):
5497class StarMap(Func):
5498    pass
key = 'starmap'
class VarMap(Func):
5501class VarMap(Func):
5502    arg_types = {"keys": True, "values": True}
5503    is_var_len_args = True
5504
5505    @property
5506    def keys(self) -> t.List[Expression]:
5507        return self.args["keys"].expressions
5508
5509    @property
5510    def values(self) -> t.List[Expression]:
5511        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5505    @property
5506    def keys(self) -> t.List[Expression]:
5507        return self.args["keys"].expressions
values: List[Expression]
5509    @property
5510    def values(self) -> t.List[Expression]:
5511        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5515class MatchAgainst(Func):
5516    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5519class Max(AggFunc):
5520    arg_types = {"this": True, "expressions": False}
5521    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5524class MD5(Func):
5525    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5529class MD5Digest(Func):
5530    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5533class Min(AggFunc):
5534    arg_types = {"this": True, "expressions": False}
5535    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5538class Month(Func):
5539    pass
key = 'month'
class AddMonths(Func):
5542class AddMonths(Func):
5543    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5546class Nvl2(Func):
5547    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5551class Predict(Func):
5552    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5555class Pow(Binary, Func):
5556    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5559class PercentileCont(AggFunc):
5560    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5563class PercentileDisc(AggFunc):
5564    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5567class Quantile(AggFunc):
5568    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5571class ApproxQuantile(Quantile):
5572    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):
5575class Quarter(Func):
5576    pass
key = 'quarter'
class Rand(Func):
5579class Rand(Func):
5580    _sql_names = ["RAND", "RANDOM"]
5581    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5584class Randn(Func):
5585    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5588class RangeN(Func):
5589    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5592class ReadCSV(Func):
5593    _sql_names = ["READ_CSV"]
5594    is_var_len_args = True
5595    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5598class Reduce(Func):
5599    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):
5602class RegexpExtract(Func):
5603    arg_types = {
5604        "this": True,
5605        "expression": True,
5606        "position": False,
5607        "occurrence": False,
5608        "parameters": False,
5609        "group": False,
5610    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5613class RegexpReplace(Func):
5614    arg_types = {
5615        "this": True,
5616        "expression": True,
5617        "replacement": False,
5618        "position": False,
5619        "occurrence": False,
5620        "modifiers": False,
5621    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5624class RegexpLike(Binary, Func):
5625    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5628class RegexpILike(Binary, Func):
5629    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5634class RegexpSplit(Func):
5635    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5638class Repeat(Func):
5639    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5644class Round(Func):
5645    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5648class RowNumber(Func):
5649    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5652class SafeDivide(Func):
5653    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5656class SHA(Func):
5657    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5660class SHA2(Func):
5661    _sql_names = ["SHA2"]
5662    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5665class Sign(Func):
5666    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5669class SortArray(Func):
5670    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5673class Split(Func):
5674    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5679class Substring(Func):
5680    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5683class StandardHash(Func):
5684    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5687class StartsWith(Func):
5688    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5689    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5692class StrPosition(Func):
5693    arg_types = {
5694        "this": True,
5695        "substr": True,
5696        "position": False,
5697        "instance": False,
5698    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5701class StrToDate(Func):
5702    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5705class StrToTime(Func):
5706    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5711class StrToUnix(Func):
5712    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5717class StrToMap(Func):
5718    arg_types = {
5719        "this": True,
5720        "pair_delim": False,
5721        "key_value_delim": False,
5722        "duplicate_resolution_callback": False,
5723    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5726class NumberToStr(Func):
5727    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5730class FromBase(Func):
5731    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5734class Struct(Func):
5735    arg_types = {"expressions": False}
5736    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5739class StructExtract(Func):
5740    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5745class Stuff(Func):
5746    _sql_names = ["STUFF", "INSERT"]
5747    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):
5750class Sum(AggFunc):
5751    pass
key = 'sum'
class Sqrt(Func):
5754class Sqrt(Func):
5755    pass
key = 'sqrt'
class Stddev(AggFunc):
5758class Stddev(AggFunc):
5759    pass
key = 'stddev'
class StddevPop(AggFunc):
5762class StddevPop(AggFunc):
5763    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5766class StddevSamp(AggFunc):
5767    pass
key = 'stddevsamp'
class TimeToStr(Func):
5770class TimeToStr(Func):
5771    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):
5774class TimeToTimeStr(Func):
5775    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5778class TimeToUnix(Func):
5779    pass
key = 'timetounix'
class TimeStrToDate(Func):
5782class TimeStrToDate(Func):
5783    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5786class TimeStrToTime(Func):
5787    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5790class TimeStrToUnix(Func):
5791    pass
key = 'timestrtounix'
class Trim(Func):
5794class Trim(Func):
5795    arg_types = {
5796        "this": True,
5797        "expression": False,
5798        "position": False,
5799        "collation": False,
5800    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5803class TsOrDsAdd(Func, TimeUnit):
5804    # return_type is used to correctly cast the arguments of this expression when transpiling it
5805    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5806
5807    @property
5808    def return_type(self) -> DataType:
5809        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
5807    @property
5808    def return_type(self) -> DataType:
5809        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5812class TsOrDsDiff(Func, TimeUnit):
5813    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5816class TsOrDsToDateStr(Func):
5817    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5820class TsOrDsToDate(Func):
5821    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5824class TsOrDsToTime(Func):
5825    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5828class TsOrDsToTimestamp(Func):
5829    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5832class TsOrDiToDi(Func):
5833    pass
key = 'tsorditodi'
class Unhex(Func):
5836class Unhex(Func):
5837    pass
key = 'unhex'
class UnixDate(Func):
5841class UnixDate(Func):
5842    pass
key = 'unixdate'
class UnixToStr(Func):
5845class UnixToStr(Func):
5846    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5851class UnixToTime(Func):
5852    arg_types = {
5853        "this": True,
5854        "scale": False,
5855        "zone": False,
5856        "hours": False,
5857        "minutes": False,
5858        "format": False,
5859    }
5860
5861    SECONDS = Literal.number(0)
5862    DECIS = Literal.number(1)
5863    CENTIS = Literal.number(2)
5864    MILLIS = Literal.number(3)
5865    DECIMILLIS = Literal.number(4)
5866    CENTIMILLIS = Literal.number(5)
5867    MICROS = Literal.number(6)
5868    DECIMICROS = Literal.number(7)
5869    CENTIMICROS = Literal.number(8)
5870    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):
5873class UnixToTimeStr(Func):
5874    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5877class TimestampFromParts(Func):
5878    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5879    arg_types = {
5880        "year": True,
5881        "month": True,
5882        "day": True,
5883        "hour": True,
5884        "min": True,
5885        "sec": True,
5886        "nano": False,
5887        "zone": False,
5888        "milli": False,
5889    }
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):
5892class Upper(Func):
5893    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5896class Corr(Binary, AggFunc):
5897    pass
key = 'corr'
class Variance(AggFunc):
5900class Variance(AggFunc):
5901    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5904class VariancePop(AggFunc):
5905    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5908class CovarSamp(Binary, AggFunc):
5909    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5912class CovarPop(Binary, AggFunc):
5913    pass
key = 'covarpop'
class Week(Func):
5916class Week(Func):
5917    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5920class XMLTable(Func):
5921    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):
5924class Year(Func):
5925    pass
key = 'year'
class Use(Expression):
5928class Use(Expression):
5929    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5932class Merge(Expression):
5933    arg_types = {
5934        "this": True,
5935        "using": True,
5936        "on": True,
5937        "expressions": True,
5938        "with": False,
5939    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5942class When(Func):
5943    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):
5948class NextValueFor(Func):
5949    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
5954class Semicolon(Expression):
5955    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:
5995def maybe_parse(
5996    sql_or_expression: ExpOrStr,
5997    *,
5998    into: t.Optional[IntoType] = None,
5999    dialect: DialectType = None,
6000    prefix: t.Optional[str] = None,
6001    copy: bool = False,
6002    **opts,
6003) -> Expression:
6004    """Gracefully handle a possible string or expression.
6005
6006    Example:
6007        >>> maybe_parse("1")
6008        Literal(this=1, is_string=False)
6009        >>> maybe_parse(to_identifier("x"))
6010        Identifier(this=x, quoted=False)
6011
6012    Args:
6013        sql_or_expression: the SQL code string or an expression
6014        into: the SQLGlot Expression to parse into
6015        dialect: the dialect used to parse the input expressions (in the case that an
6016            input expression is a SQL string).
6017        prefix: a string to prefix the sql with before it gets parsed
6018            (automatically includes a space)
6019        copy: whether to copy the expression.
6020        **opts: other options to use to parse the input expressions (again, in the case
6021            that an input expression is a SQL string).
6022
6023    Returns:
6024        Expression: the parsed or given expression.
6025    """
6026    if isinstance(sql_or_expression, Expression):
6027        if copy:
6028            return sql_or_expression.copy()
6029        return sql_or_expression
6030
6031    if sql_or_expression is None:
6032        raise ParseError("SQL cannot be None")
6033
6034    import sqlglot
6035
6036    sql = str(sql_or_expression)
6037    if prefix:
6038        sql = f"{prefix} {sql}"
6039
6040    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):
6051def maybe_copy(instance, copy=True):
6052    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:
6266def union(
6267    left: ExpOrStr,
6268    right: ExpOrStr,
6269    distinct: bool = True,
6270    dialect: DialectType = None,
6271    copy: bool = True,
6272    **opts,
6273) -> Union:
6274    """
6275    Initializes a syntax tree from one UNION expression.
6276
6277    Example:
6278        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6279        'SELECT * FROM foo UNION SELECT * FROM bla'
6280
6281    Args:
6282        left: the SQL code string corresponding to the left-hand side.
6283            If an `Expression` instance is passed, it will be used as-is.
6284        right: the SQL code string corresponding to the right-hand side.
6285            If an `Expression` instance is passed, it will be used as-is.
6286        distinct: set the DISTINCT flag if and only if this is true.
6287        dialect: the dialect used to parse the input expression.
6288        copy: whether to copy the expression.
6289        opts: other options to use to parse the input expressions.
6290
6291    Returns:
6292        The new Union instance.
6293    """
6294    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6295    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6296
6297    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:
6300def intersect(
6301    left: ExpOrStr,
6302    right: ExpOrStr,
6303    distinct: bool = True,
6304    dialect: DialectType = None,
6305    copy: bool = True,
6306    **opts,
6307) -> Intersect:
6308    """
6309    Initializes a syntax tree from one INTERSECT expression.
6310
6311    Example:
6312        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6313        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6314
6315    Args:
6316        left: the SQL code string corresponding to the left-hand side.
6317            If an `Expression` instance is passed, it will be used as-is.
6318        right: the SQL code string corresponding to the right-hand side.
6319            If an `Expression` instance is passed, it will be used as-is.
6320        distinct: set the DISTINCT flag if and only if this is true.
6321        dialect: the dialect used to parse the input expression.
6322        copy: whether to copy the expression.
6323        opts: other options to use to parse the input expressions.
6324
6325    Returns:
6326        The new Intersect instance.
6327    """
6328    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6329    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6330
6331    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:
6334def except_(
6335    left: ExpOrStr,
6336    right: ExpOrStr,
6337    distinct: bool = True,
6338    dialect: DialectType = None,
6339    copy: bool = True,
6340    **opts,
6341) -> Except:
6342    """
6343    Initializes a syntax tree from one EXCEPT expression.
6344
6345    Example:
6346        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6347        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6348
6349    Args:
6350        left: the SQL code string corresponding to the left-hand side.
6351            If an `Expression` instance is passed, it will be used as-is.
6352        right: the SQL code string corresponding to the right-hand side.
6353            If an `Expression` instance is passed, it will be used as-is.
6354        distinct: set the DISTINCT flag if and only if this is true.
6355        dialect: the dialect used to parse the input expression.
6356        copy: whether to copy the expression.
6357        opts: other options to use to parse the input expressions.
6358
6359    Returns:
6360        The new Except instance.
6361    """
6362    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6363    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6364
6365    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:
6368def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6369    """
6370    Initializes a syntax tree from one or multiple SELECT expressions.
6371
6372    Example:
6373        >>> select("col1", "col2").from_("tbl").sql()
6374        'SELECT col1, col2 FROM tbl'
6375
6376    Args:
6377        *expressions: the SQL code string to parse as the expressions of a
6378            SELECT statement. If an Expression instance is passed, this is used as-is.
6379        dialect: the dialect used to parse the input expressions (in the case that an
6380            input expression is a SQL string).
6381        **opts: other options to use to parse the input expressions (again, in the case
6382            that an input expression is a SQL string).
6383
6384    Returns:
6385        Select: the syntax tree for the SELECT statement.
6386    """
6387    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:
6390def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6391    """
6392    Initializes a syntax tree from a FROM expression.
6393
6394    Example:
6395        >>> from_("tbl").select("col1", "col2").sql()
6396        'SELECT col1, col2 FROM tbl'
6397
6398    Args:
6399        *expression: the SQL code string to parse as the FROM expressions of a
6400            SELECT statement. If an Expression instance is passed, this is used as-is.
6401        dialect: the dialect used to parse the input expression (in the case that the
6402            input expression is a SQL string).
6403        **opts: other options to use to parse the input expressions (again, in the case
6404            that the input expression is a SQL string).
6405
6406    Returns:
6407        Select: the syntax tree for the SELECT statement.
6408    """
6409    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:
6412def update(
6413    table: str | Table,
6414    properties: dict,
6415    where: t.Optional[ExpOrStr] = None,
6416    from_: t.Optional[ExpOrStr] = None,
6417    dialect: DialectType = None,
6418    **opts,
6419) -> Update:
6420    """
6421    Creates an update statement.
6422
6423    Example:
6424        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6425        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6426
6427    Args:
6428        *properties: dictionary of properties to set which are
6429            auto converted to sql objects eg None -> NULL
6430        where: sql conditional parsed into a WHERE statement
6431        from_: sql statement parsed into a FROM statement
6432        dialect: the dialect used to parse the input expressions.
6433        **opts: other options to use to parse the input expressions.
6434
6435    Returns:
6436        Update: the syntax tree for the UPDATE statement.
6437    """
6438    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6439    update_expr.set(
6440        "expressions",
6441        [
6442            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6443            for k, v in properties.items()
6444        ],
6445    )
6446    if from_:
6447        update_expr.set(
6448            "from",
6449            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6450        )
6451    if isinstance(where, Condition):
6452        where = Where(this=where)
6453    if where:
6454        update_expr.set(
6455            "where",
6456            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6457        )
6458    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:
6461def delete(
6462    table: ExpOrStr,
6463    where: t.Optional[ExpOrStr] = None,
6464    returning: t.Optional[ExpOrStr] = None,
6465    dialect: DialectType = None,
6466    **opts,
6467) -> Delete:
6468    """
6469    Builds a delete statement.
6470
6471    Example:
6472        >>> delete("my_table", where="id > 1").sql()
6473        'DELETE FROM my_table WHERE id > 1'
6474
6475    Args:
6476        where: sql conditional parsed into a WHERE statement
6477        returning: sql conditional parsed into a RETURNING statement
6478        dialect: the dialect used to parse the input expressions.
6479        **opts: other options to use to parse the input expressions.
6480
6481    Returns:
6482        Delete: the syntax tree for the DELETE statement.
6483    """
6484    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6485    if where:
6486        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6487    if returning:
6488        delete_expr = t.cast(
6489            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6490        )
6491    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:
6494def insert(
6495    expression: ExpOrStr,
6496    into: ExpOrStr,
6497    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6498    overwrite: t.Optional[bool] = None,
6499    returning: t.Optional[ExpOrStr] = None,
6500    dialect: DialectType = None,
6501    copy: bool = True,
6502    **opts,
6503) -> Insert:
6504    """
6505    Builds an INSERT statement.
6506
6507    Example:
6508        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6509        'INSERT INTO tbl VALUES (1, 2, 3)'
6510
6511    Args:
6512        expression: the sql string or expression of the INSERT statement
6513        into: the tbl to insert data to.
6514        columns: optionally the table's column names.
6515        overwrite: whether to INSERT OVERWRITE or not.
6516        returning: sql conditional parsed into a RETURNING statement
6517        dialect: the dialect used to parse the input expressions.
6518        copy: whether to copy the expression.
6519        **opts: other options to use to parse the input expressions.
6520
6521    Returns:
6522        Insert: the syntax tree for the INSERT statement.
6523    """
6524    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6525    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6526
6527    if columns:
6528        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6529
6530    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6531
6532    if returning:
6533        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6534
6535    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:
6538def condition(
6539    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6540) -> Condition:
6541    """
6542    Initialize a logical condition expression.
6543
6544    Example:
6545        >>> condition("x=1").sql()
6546        'x = 1'
6547
6548        This is helpful for composing larger logical syntax trees:
6549        >>> where = condition("x=1")
6550        >>> where = where.and_("y=1")
6551        >>> Select().from_("tbl").select("*").where(where).sql()
6552        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6553
6554    Args:
6555        *expression: the SQL code string to parse.
6556            If an Expression instance is passed, this is used as-is.
6557        dialect: the dialect used to parse the input expression (in the case that the
6558            input expression is a SQL string).
6559        copy: Whether to copy `expression` (only applies to expressions).
6560        **opts: other options to use to parse the input expressions (again, in the case
6561            that the input expression is a SQL string).
6562
6563    Returns:
6564        The new Condition instance
6565    """
6566    return maybe_parse(
6567        expression,
6568        into=Condition,
6569        dialect=dialect,
6570        copy=copy,
6571        **opts,
6572    )

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:
6575def and_(
6576    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6577) -> Condition:
6578    """
6579    Combine multiple conditions with an AND logical operator.
6580
6581    Example:
6582        >>> and_("x=1", and_("y=1", "z=1")).sql()
6583        'x = 1 AND (y = 1 AND z = 1)'
6584
6585    Args:
6586        *expressions: the SQL code strings to parse.
6587            If an Expression instance is passed, this is used as-is.
6588        dialect: the dialect used to parse the input expression.
6589        copy: whether to copy `expressions` (only applies to Expressions).
6590        **opts: other options to use to parse the input expressions.
6591
6592    Returns:
6593        The new condition
6594    """
6595    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:
6598def or_(
6599    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6600) -> Condition:
6601    """
6602    Combine multiple conditions with an OR logical operator.
6603
6604    Example:
6605        >>> or_("x=1", or_("y=1", "z=1")).sql()
6606        'x = 1 OR (y = 1 OR z = 1)'
6607
6608    Args:
6609        *expressions: the SQL code strings to parse.
6610            If an Expression instance is passed, this is used as-is.
6611        dialect: the dialect used to parse the input expression.
6612        copy: whether to copy `expressions` (only applies to Expressions).
6613        **opts: other options to use to parse the input expressions.
6614
6615    Returns:
6616        The new condition
6617    """
6618    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:
6621def xor(
6622    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6623) -> Condition:
6624    """
6625    Combine multiple conditions with an XOR logical operator.
6626
6627    Example:
6628        >>> xor("x=1", xor("y=1", "z=1")).sql()
6629        'x = 1 XOR (y = 1 XOR z = 1)'
6630
6631    Args:
6632        *expressions: the SQL code strings to parse.
6633            If an Expression instance is passed, this is used as-is.
6634        dialect: the dialect used to parse the input expression.
6635        copy: whether to copy `expressions` (only applies to Expressions).
6636        **opts: other options to use to parse the input expressions.
6637
6638    Returns:
6639        The new condition
6640    """
6641    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:
6644def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6645    """
6646    Wrap a condition with a NOT operator.
6647
6648    Example:
6649        >>> not_("this_suit='black'").sql()
6650        "NOT this_suit = 'black'"
6651
6652    Args:
6653        expression: the SQL code string to parse.
6654            If an Expression instance is passed, this is used as-is.
6655        dialect: the dialect used to parse the input expression.
6656        copy: whether to copy the expression or not.
6657        **opts: other options to use to parse the input expressions.
6658
6659    Returns:
6660        The new condition.
6661    """
6662    this = condition(
6663        expression,
6664        dialect=dialect,
6665        copy=copy,
6666        **opts,
6667    )
6668    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:
6671def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6672    """
6673    Wrap an expression in parentheses.
6674
6675    Example:
6676        >>> paren("5 + 3").sql()
6677        '(5 + 3)'
6678
6679    Args:
6680        expression: the SQL code string to parse.
6681            If an Expression instance is passed, this is used as-is.
6682        copy: whether to copy the expression or not.
6683
6684    Returns:
6685        The wrapped expression.
6686    """
6687    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):
6703def to_identifier(name, quoted=None, copy=True):
6704    """Builds an identifier.
6705
6706    Args:
6707        name: The name to turn into an identifier.
6708        quoted: Whether to force quote the identifier.
6709        copy: Whether to copy name if it's an Identifier.
6710
6711    Returns:
6712        The identifier ast node.
6713    """
6714
6715    if name is None:
6716        return None
6717
6718    if isinstance(name, Identifier):
6719        identifier = maybe_copy(name, copy)
6720    elif isinstance(name, str):
6721        identifier = Identifier(
6722            this=name,
6723            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6724        )
6725    else:
6726        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6727    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:
6730def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6731    """
6732    Parses a given string into an identifier.
6733
6734    Args:
6735        name: The name to parse into an identifier.
6736        dialect: The dialect to parse against.
6737
6738    Returns:
6739        The identifier ast node.
6740    """
6741    try:
6742        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6743    except ParseError:
6744        expression = to_identifier(name)
6745
6746    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:
6752def to_interval(interval: str | Literal) -> Interval:
6753    """Builds an interval expression from a string like '1 day' or '5 months'."""
6754    if isinstance(interval, Literal):
6755        if not interval.is_string:
6756            raise ValueError("Invalid interval string.")
6757
6758        interval = interval.this
6759
6760    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6761
6762    if not interval_parts:
6763        raise ValueError("Invalid interval string.")
6764
6765    return Interval(
6766        this=Literal.string(interval_parts.group(1)),
6767        unit=Var(this=interval_parts.group(2).upper()),
6768    )

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:
6771def to_table(
6772    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6773) -> Table:
6774    """
6775    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6776    If a table is passed in then that table is returned.
6777
6778    Args:
6779        sql_path: a `[catalog].[schema].[table]` string.
6780        dialect: the source dialect according to which the table name will be parsed.
6781        copy: Whether to copy a table if it is passed in.
6782        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6783
6784    Returns:
6785        A table expression.
6786    """
6787    if isinstance(sql_path, Table):
6788        return maybe_copy(sql_path, copy=copy)
6789
6790    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6791
6792    for k, v in kwargs.items():
6793        table.set(k, v)
6794
6795    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:
6798def to_column(
6799    sql_path: str | Column,
6800    quoted: t.Optional[bool] = None,
6801    dialect: DialectType = None,
6802    copy: bool = True,
6803    **kwargs,
6804) -> Column:
6805    """
6806    Create a column from a `[table].[column]` sql path. Table is optional.
6807    If a column is passed in then that column is returned.
6808
6809    Args:
6810        sql_path: a `[table].[column]` string.
6811        quoted: Whether or not to force quote identifiers.
6812        dialect: the source dialect according to which the column name will be parsed.
6813        copy: Whether to copy a column if it is passed in.
6814        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6815
6816    Returns:
6817        A column expression.
6818    """
6819    if isinstance(sql_path, Column):
6820        return maybe_copy(sql_path, copy=copy)
6821
6822    try:
6823        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6824    except ParseError:
6825        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6826
6827    for k, v in kwargs.items():
6828        col.set(k, v)
6829
6830    if quoted:
6831        for i in col.find_all(Identifier):
6832            i.set("quoted", True)
6833
6834    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):
6837def alias_(
6838    expression: ExpOrStr,
6839    alias: t.Optional[str | Identifier],
6840    table: bool | t.Sequence[str | Identifier] = False,
6841    quoted: t.Optional[bool] = None,
6842    dialect: DialectType = None,
6843    copy: bool = True,
6844    **opts,
6845):
6846    """Create an Alias expression.
6847
6848    Example:
6849        >>> alias_('foo', 'bar').sql()
6850        'foo AS bar'
6851
6852        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6853        '(SELECT 1, 2) AS bar(a, b)'
6854
6855    Args:
6856        expression: the SQL code strings to parse.
6857            If an Expression instance is passed, this is used as-is.
6858        alias: the alias name to use. If the name has
6859            special characters it is quoted.
6860        table: Whether to create a table alias, can also be a list of columns.
6861        quoted: whether to quote the alias
6862        dialect: the dialect used to parse the input expression.
6863        copy: Whether to copy the expression.
6864        **opts: other options to use to parse the input expressions.
6865
6866    Returns:
6867        Alias: the aliased expression
6868    """
6869    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6870    alias = to_identifier(alias, quoted=quoted)
6871
6872    if table:
6873        table_alias = TableAlias(this=alias)
6874        exp.set("alias", table_alias)
6875
6876        if not isinstance(table, bool):
6877            for column in table:
6878                table_alias.append("columns", to_identifier(column, quoted=quoted))
6879
6880        return exp
6881
6882    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6883    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6884    # for the complete Window expression.
6885    #
6886    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6887
6888    if "alias" in exp.arg_types and not isinstance(exp, Window):
6889        exp.set("alias", alias)
6890        return exp
6891    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:
6894def subquery(
6895    expression: ExpOrStr,
6896    alias: t.Optional[Identifier | str] = None,
6897    dialect: DialectType = None,
6898    **opts,
6899) -> Select:
6900    """
6901    Build a subquery expression that's selected from.
6902
6903    Example:
6904        >>> subquery('select x from tbl', 'bar').select('x').sql()
6905        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6906
6907    Args:
6908        expression: the SQL code strings to parse.
6909            If an Expression instance is passed, this is used as-is.
6910        alias: the alias name to use.
6911        dialect: the dialect used to parse the input expression.
6912        **opts: other options to use to parse the input expressions.
6913
6914    Returns:
6915        A new Select instance with the subquery expression included.
6916    """
6917
6918    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
6919    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):
6950def column(
6951    col,
6952    table=None,
6953    db=None,
6954    catalog=None,
6955    *,
6956    fields=None,
6957    quoted=None,
6958    copy=True,
6959):
6960    """
6961    Build a Column.
6962
6963    Args:
6964        col: Column name.
6965        table: Table name.
6966        db: Database name.
6967        catalog: Catalog name.
6968        fields: Additional fields using dots.
6969        quoted: Whether to force quotes on the column's identifiers.
6970        copy: Whether to copy identifiers if passed in.
6971
6972    Returns:
6973        The new Column instance.
6974    """
6975    this = Column(
6976        this=to_identifier(col, quoted=quoted, copy=copy),
6977        table=to_identifier(table, quoted=quoted, copy=copy),
6978        db=to_identifier(db, quoted=quoted, copy=copy),
6979        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6980    )
6981
6982    if fields:
6983        this = Dot.build(
6984            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
6985        )
6986    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:
6989def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6990    """Cast an expression to a data type.
6991
6992    Example:
6993        >>> cast('x + 1', 'int').sql()
6994        'CAST(x + 1 AS INT)'
6995
6996    Args:
6997        expression: The expression to cast.
6998        to: The datatype to cast to.
6999        copy: Whether to copy the supplied expressions.
7000
7001    Returns:
7002        The new Cast instance.
7003    """
7004    expr = maybe_parse(expression, copy=copy, **opts)
7005    data_type = DataType.build(to, copy=copy, **opts)
7006
7007    if expr.is_type(data_type):
7008        return expr
7009
7010    expr = Cast(this=expr, to=data_type)
7011    expr.type = data_type
7012
7013    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:
7016def table_(
7017    table: Identifier | str,
7018    db: t.Optional[Identifier | str] = None,
7019    catalog: t.Optional[Identifier | str] = None,
7020    quoted: t.Optional[bool] = None,
7021    alias: t.Optional[Identifier | str] = None,
7022) -> Table:
7023    """Build a Table.
7024
7025    Args:
7026        table: Table name.
7027        db: Database name.
7028        catalog: Catalog name.
7029        quote: Whether to force quotes on the table's identifiers.
7030        alias: Table's alias.
7031
7032    Returns:
7033        The new Table instance.
7034    """
7035    return Table(
7036        this=to_identifier(table, quoted=quoted) if table else None,
7037        db=to_identifier(db, quoted=quoted) if db else None,
7038        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7039        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7040    )

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:
7043def values(
7044    values: t.Iterable[t.Tuple[t.Any, ...]],
7045    alias: t.Optional[str] = None,
7046    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7047) -> Values:
7048    """Build VALUES statement.
7049
7050    Example:
7051        >>> values([(1, '2')]).sql()
7052        "VALUES (1, '2')"
7053
7054    Args:
7055        values: values statements that will be converted to SQL
7056        alias: optional alias
7057        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7058         If either are provided then an alias is also required.
7059
7060    Returns:
7061        Values: the Values expression object
7062    """
7063    if columns and not alias:
7064        raise ValueError("Alias is required when providing columns")
7065
7066    return Values(
7067        expressions=[convert(tup) for tup in values],
7068        alias=(
7069            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7070            if columns
7071            else (TableAlias(this=to_identifier(alias)) if alias else None)
7072        ),
7073    )

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:
7076def var(name: t.Optional[ExpOrStr]) -> Var:
7077    """Build a SQL variable.
7078
7079    Example:
7080        >>> repr(var('x'))
7081        'Var(this=x)'
7082
7083        >>> repr(var(column('x', table='y')))
7084        'Var(this=x)'
7085
7086    Args:
7087        name: The name of the var or an expression who's name will become the var.
7088
7089    Returns:
7090        The new variable node.
7091    """
7092    if not name:
7093        raise ValueError("Cannot convert empty name into var.")
7094
7095    if isinstance(name, Expression):
7096        name = name.name
7097    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:
7100def rename_table(
7101    old_name: str | Table,
7102    new_name: str | Table,
7103    dialect: DialectType = None,
7104) -> AlterTable:
7105    """Build ALTER TABLE... RENAME... expression
7106
7107    Args:
7108        old_name: The old name of the table
7109        new_name: The new name of the table
7110        dialect: The dialect to parse the table.
7111
7112    Returns:
7113        Alter table expression
7114    """
7115    old_table = to_table(old_name, dialect=dialect)
7116    new_table = to_table(new_name, dialect=dialect)
7117    return AlterTable(
7118        this=old_table,
7119        actions=[
7120            RenameTable(this=new_table),
7121        ],
7122    )

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:
7125def rename_column(
7126    table_name: str | Table,
7127    old_column_name: str | Column,
7128    new_column_name: str | Column,
7129    exists: t.Optional[bool] = None,
7130    dialect: DialectType = None,
7131) -> AlterTable:
7132    """Build ALTER TABLE... RENAME COLUMN... expression
7133
7134    Args:
7135        table_name: Name of the table
7136        old_column: The old name of the column
7137        new_column: The new name of the column
7138        exists: Whether to add the `IF EXISTS` clause
7139        dialect: The dialect to parse the table/column.
7140
7141    Returns:
7142        Alter table expression
7143    """
7144    table = to_table(table_name, dialect=dialect)
7145    old_column = to_column(old_column_name, dialect=dialect)
7146    new_column = to_column(new_column_name, dialect=dialect)
7147    return AlterTable(
7148        this=table,
7149        actions=[
7150            RenameColumn(this=old_column, to=new_column, exists=exists),
7151        ],
7152    )

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

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:
7286def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7287    """Get the full name of a table as a string.
7288
7289    Args:
7290        table: Table expression node or string.
7291        dialect: The dialect to generate the table name for.
7292        identify: Determines when an identifier should be quoted. Possible values are:
7293            False (default): Never quote, except in cases where it's mandatory by the dialect.
7294            True: Always quote.
7295
7296    Examples:
7297        >>> from sqlglot import exp, parse_one
7298        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7299        'a.b.c'
7300
7301    Returns:
7302        The table name.
7303    """
7304
7305    table = maybe_parse(table, into=Table, dialect=dialect)
7306
7307    if not table:
7308        raise ValueError(f"Cannot parse {table}")
7309
7310    return ".".join(
7311        (
7312            part.sql(dialect=dialect, identify=True, copy=False)
7313            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7314            else part.name
7315        )
7316        for part in table.parts
7317    )

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:
7320def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7321    """Returns a case normalized table name without quotes.
7322
7323    Args:
7324        table: the table to normalize
7325        dialect: the dialect to use for normalization rules
7326        copy: whether to copy the expression.
7327
7328    Examples:
7329        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7330        'A-B.c'
7331    """
7332    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7333
7334    return ".".join(
7335        p.name
7336        for p in normalize_identifiers(
7337            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7338        ).parts
7339    )

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

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:
7569def tuple_(
7570    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7571) -> Tuple:
7572    """
7573    Returns an tuple.
7574
7575    Examples:
7576        >>> tuple_(1, 'x').sql()
7577        '(1, x)'
7578
7579    Args:
7580        expressions: the expressions to add to the tuple.
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        A tuple expression.
7587    """
7588    return Tuple(
7589        expressions=[
7590            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7591            for expression in expressions
7592        ]
7593    )

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:
7596def true() -> Boolean:
7597    """
7598    Returns a true Boolean expression.
7599    """
7600    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7603def false() -> Boolean:
7604    """
7605    Returns a false Boolean expression.
7606    """
7607    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7610def null() -> Null:
7611    """
7612    Returns a Null expression.
7613    """
7614    return Null()

Returns a Null expression.

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