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

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

def to_dot(self) -> Dot | Identifier:
1580    def to_dot(self) -> Dot | Identifier:
1581        """Converts the column into a dot expression."""
1582        parts = self.parts
1583        parent = self.parent
1584
1585        while parent:
1586            if isinstance(parent, Dot):
1587                parts.append(parent.expression)
1588            parent = parent.parent
1589
1590        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1593class ColumnPosition(Expression):
1594    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1597class ColumnDef(Expression):
1598    arg_types = {
1599        "this": True,
1600        "kind": False,
1601        "constraints": False,
1602        "exists": False,
1603        "position": False,
1604    }
1605
1606    @property
1607    def constraints(self) -> t.List[ColumnConstraint]:
1608        return self.args.get("constraints") or []
1609
1610    @property
1611    def kind(self) -> t.Optional[DataType]:
1612        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1606    @property
1607    def constraints(self) -> t.List[ColumnConstraint]:
1608        return self.args.get("constraints") or []
kind: Optional[DataType]
1610    @property
1611    def kind(self) -> t.Optional[DataType]:
1612        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1615class AlterColumn(Expression):
1616    arg_types = {
1617        "this": True,
1618        "dtype": False,
1619        "collate": False,
1620        "using": False,
1621        "default": False,
1622        "drop": False,
1623        "comment": False,
1624    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1627class RenameColumn(Expression):
1628    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1631class RenameTable(Expression):
1632    pass
key = 'renametable'
class SwapTable(Expression):
1635class SwapTable(Expression):
1636    pass
key = 'swaptable'
class Comment(Expression):
1639class Comment(Expression):
1640    arg_types = {
1641        "this": True,
1642        "kind": True,
1643        "expression": True,
1644        "exists": False,
1645        "materialized": False,
1646    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1649class Comprehension(Expression):
1650    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):
1654class MergeTreeTTLAction(Expression):
1655    arg_types = {
1656        "this": True,
1657        "delete": False,
1658        "recompress": False,
1659        "to_disk": False,
1660        "to_volume": False,
1661    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1665class MergeTreeTTL(Expression):
1666    arg_types = {
1667        "expressions": True,
1668        "where": False,
1669        "group": False,
1670        "aggregates": False,
1671    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1675class IndexConstraintOption(Expression):
1676    arg_types = {
1677        "key_block_size": False,
1678        "using": False,
1679        "parser": False,
1680        "comment": False,
1681        "visible": False,
1682        "engine_attr": False,
1683        "secondary_engine_attr": False,
1684    }
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):
1687class ColumnConstraint(Expression):
1688    arg_types = {"this": False, "kind": True}
1689
1690    @property
1691    def kind(self) -> ColumnConstraintKind:
1692        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1690    @property
1691    def kind(self) -> ColumnConstraintKind:
1692        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1695class ColumnConstraintKind(Expression):
1696    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1699class AutoIncrementColumnConstraint(ColumnConstraintKind):
1700    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1703class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1704    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1707class CaseSpecificColumnConstraint(ColumnConstraintKind):
1708    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1711class CharacterSetColumnConstraint(ColumnConstraintKind):
1712    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1715class CheckColumnConstraint(ColumnConstraintKind):
1716    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1719class ClusteredColumnConstraint(ColumnConstraintKind):
1720    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1723class CollateColumnConstraint(ColumnConstraintKind):
1724    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1727class CommentColumnConstraint(ColumnConstraintKind):
1728    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1731class CompressColumnConstraint(ColumnConstraintKind):
1732    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1735class DateFormatColumnConstraint(ColumnConstraintKind):
1736    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1739class DefaultColumnConstraint(ColumnConstraintKind):
1740    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1743class EncodeColumnConstraint(ColumnConstraintKind):
1744    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1748class ExcludeColumnConstraint(ColumnConstraintKind):
1749    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1752class EphemeralColumnConstraint(ColumnConstraintKind):
1753    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1756class WithOperator(Expression):
1757    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1760class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1761    # this: True -> ALWAYS, this: False -> BY DEFAULT
1762    arg_types = {
1763        "this": False,
1764        "expression": False,
1765        "on_null": False,
1766        "start": False,
1767        "increment": False,
1768        "minvalue": False,
1769        "maxvalue": False,
1770        "cycle": False,
1771    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1774class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1775    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1780class IndexColumnConstraint(ColumnConstraintKind):
1781    arg_types = {
1782        "this": False,
1783        "expressions": False,
1784        "kind": False,
1785        "index_type": False,
1786        "options": False,
1787        "expression": False,  # Clickhouse
1788        "granularity": False,
1789    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1792class InlineLengthColumnConstraint(ColumnConstraintKind):
1793    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1796class NonClusteredColumnConstraint(ColumnConstraintKind):
1797    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1800class NotForReplicationColumnConstraint(ColumnConstraintKind):
1801    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1804class NotNullColumnConstraint(ColumnConstraintKind):
1805    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1809class OnUpdateColumnConstraint(ColumnConstraintKind):
1810    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1814class TransformColumnConstraint(ColumnConstraintKind):
1815    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1818class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1819    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1822class TitleColumnConstraint(ColumnConstraintKind):
1823    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1826class UniqueColumnConstraint(ColumnConstraintKind):
1827    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):
1830class UppercaseColumnConstraint(ColumnConstraintKind):
1831    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1834class PathColumnConstraint(ColumnConstraintKind):
1835    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1840class ComputedColumnConstraint(ColumnConstraintKind):
1841    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1844class Constraint(Expression):
1845    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1848class Delete(DML):
1849    arg_types = {
1850        "with": False,
1851        "this": False,
1852        "using": False,
1853        "where": False,
1854        "returning": False,
1855        "limit": False,
1856        "tables": False,  # Multiple-Table Syntax (MySQL)
1857    }
1858
1859    def delete(
1860        self,
1861        table: ExpOrStr,
1862        dialect: DialectType = None,
1863        copy: bool = True,
1864        **opts,
1865    ) -> Delete:
1866        """
1867        Create a DELETE expression or replace the table on an existing DELETE expression.
1868
1869        Example:
1870            >>> delete("tbl").sql()
1871            'DELETE FROM tbl'
1872
1873        Args:
1874            table: the table from which to delete.
1875            dialect: the dialect used to parse the input expression.
1876            copy: if `False`, modify this expression instance in-place.
1877            opts: other options to use to parse the input expressions.
1878
1879        Returns:
1880            Delete: the modified expression.
1881        """
1882        return _apply_builder(
1883            expression=table,
1884            instance=self,
1885            arg="this",
1886            dialect=dialect,
1887            into=Table,
1888            copy=copy,
1889            **opts,
1890        )
1891
1892    def where(
1893        self,
1894        *expressions: t.Optional[ExpOrStr],
1895        append: bool = True,
1896        dialect: DialectType = None,
1897        copy: bool = True,
1898        **opts,
1899    ) -> Delete:
1900        """
1901        Append to or set the WHERE expressions.
1902
1903        Example:
1904            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1905            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1906
1907        Args:
1908            *expressions: the SQL code strings to parse.
1909                If an `Expression` instance is passed, it will be used as-is.
1910                Multiple expressions are combined with an AND operator.
1911            append: if `True`, AND the new expressions to any existing expression.
1912                Otherwise, this resets the expression.
1913            dialect: the dialect used to parse the input expressions.
1914            copy: if `False`, modify this expression instance in-place.
1915            opts: other options to use to parse the input expressions.
1916
1917        Returns:
1918            Delete: the modified expression.
1919        """
1920        return _apply_conjunction_builder(
1921            *expressions,
1922            instance=self,
1923            arg="where",
1924            append=append,
1925            into=Where,
1926            dialect=dialect,
1927            copy=copy,
1928            **opts,
1929        )
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:
1859    def delete(
1860        self,
1861        table: ExpOrStr,
1862        dialect: DialectType = None,
1863        copy: bool = True,
1864        **opts,
1865    ) -> Delete:
1866        """
1867        Create a DELETE expression or replace the table on an existing DELETE expression.
1868
1869        Example:
1870            >>> delete("tbl").sql()
1871            'DELETE FROM tbl'
1872
1873        Args:
1874            table: the table from which to delete.
1875            dialect: the dialect used to parse the input expression.
1876            copy: if `False`, modify this expression instance in-place.
1877            opts: other options to use to parse the input expressions.
1878
1879        Returns:
1880            Delete: the modified expression.
1881        """
1882        return _apply_builder(
1883            expression=table,
1884            instance=self,
1885            arg="this",
1886            dialect=dialect,
1887            into=Table,
1888            copy=copy,
1889            **opts,
1890        )

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:
1892    def where(
1893        self,
1894        *expressions: t.Optional[ExpOrStr],
1895        append: bool = True,
1896        dialect: DialectType = None,
1897        copy: bool = True,
1898        **opts,
1899    ) -> Delete:
1900        """
1901        Append to or set the WHERE expressions.
1902
1903        Example:
1904            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1905            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1906
1907        Args:
1908            *expressions: the SQL code strings to parse.
1909                If an `Expression` instance is passed, it will be used as-is.
1910                Multiple expressions are combined with an AND operator.
1911            append: if `True`, AND the new expressions to any existing expression.
1912                Otherwise, this resets the expression.
1913            dialect: the dialect used to parse the input expressions.
1914            copy: if `False`, modify this expression instance in-place.
1915            opts: other options to use to parse the input expressions.
1916
1917        Returns:
1918            Delete: the modified expression.
1919        """
1920        return _apply_conjunction_builder(
1921            *expressions,
1922            instance=self,
1923            arg="where",
1924            append=append,
1925            into=Where,
1926            dialect=dialect,
1927            copy=copy,
1928            **opts,
1929        )

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):
1932class Drop(Expression):
1933    arg_types = {
1934        "this": False,
1935        "kind": False,
1936        "expressions": False,
1937        "exists": False,
1938        "temporary": False,
1939        "materialized": False,
1940        "cascade": False,
1941        "constraints": False,
1942        "purge": False,
1943    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1946class Filter(Expression):
1947    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1950class Check(Expression):
1951    pass
key = 'check'
class Connect(Expression):
1955class Connect(Expression):
1956    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
1959class CopyParameter(Expression):
1960    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'copyparameter'
class Copy(Expression):
1963class Copy(Expression):
1964    arg_types = {
1965        "this": True,
1966        "kind": True,
1967        "files": True,
1968        "credentials": False,
1969        "format": False,
1970        "params": False,
1971    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
1974class Credentials(Expression):
1975    arg_types = {
1976        "credentials": False,
1977        "encryption": False,
1978        "storage": False,
1979        "iam_role": False,
1980        "region": False,
1981    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
1984class Prior(Expression):
1985    pass
key = 'prior'
class Directory(Expression):
1988class Directory(Expression):
1989    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1990    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1993class ForeignKey(Expression):
1994    arg_types = {
1995        "expressions": True,
1996        "reference": False,
1997        "delete": False,
1998        "update": False,
1999    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2002class ColumnPrefix(Expression):
2003    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2006class PrimaryKey(Expression):
2007    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2012class Into(Expression):
2013    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2016class From(Expression):
2017    @property
2018    def name(self) -> str:
2019        return self.this.name
2020
2021    @property
2022    def alias_or_name(self) -> str:
2023        return self.this.alias_or_name
name: str
2017    @property
2018    def name(self) -> str:
2019        return self.this.name
alias_or_name: str
2021    @property
2022    def alias_or_name(self) -> str:
2023        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2026class Having(Expression):
2027    pass
key = 'having'
class Hint(Expression):
2030class Hint(Expression):
2031    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2034class JoinHint(Expression):
2035    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2038class Identifier(Expression):
2039    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2040
2041    @property
2042    def quoted(self) -> bool:
2043        return bool(self.args.get("quoted"))
2044
2045    @property
2046    def hashable_args(self) -> t.Any:
2047        return (self.this, self.quoted)
2048
2049    @property
2050    def output_name(self) -> str:
2051        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2041    @property
2042    def quoted(self) -> bool:
2043        return bool(self.args.get("quoted"))
hashable_args: Any
2045    @property
2046    def hashable_args(self) -> t.Any:
2047        return (self.this, self.quoted)
output_name: str
2049    @property
2050    def output_name(self) -> str:
2051        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):
2055class Opclass(Expression):
2056    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2059class Index(Expression):
2060    arg_types = {
2061        "this": False,
2062        "table": False,
2063        "unique": False,
2064        "primary": False,
2065        "amp": False,  # teradata
2066        "params": False,
2067    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2070class IndexParameters(Expression):
2071    arg_types = {
2072        "using": False,
2073        "include": False,
2074        "columns": False,
2075        "with_storage": False,
2076        "partition_by": False,
2077        "tablespace": False,
2078        "where": False,
2079    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
2082class Insert(DDL, DML):
2083    arg_types = {
2084        "hint": False,
2085        "with": False,
2086        "is_function": False,
2087        "this": True,
2088        "expression": False,
2089        "conflict": False,
2090        "returning": False,
2091        "overwrite": False,
2092        "exists": False,
2093        "alternative": False,
2094        "where": False,
2095        "ignore": False,
2096        "by_name": False,
2097        "stored": False,
2098    }
2099
2100    def with_(
2101        self,
2102        alias: ExpOrStr,
2103        as_: ExpOrStr,
2104        recursive: t.Optional[bool] = None,
2105        append: bool = True,
2106        dialect: DialectType = None,
2107        copy: bool = True,
2108        **opts,
2109    ) -> Insert:
2110        """
2111        Append to or set the common table expressions.
2112
2113        Example:
2114            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2115            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2116
2117        Args:
2118            alias: the SQL code string to parse as the table name.
2119                If an `Expression` instance is passed, this is used as-is.
2120            as_: the SQL code string to parse as the table expression.
2121                If an `Expression` instance is passed, it will be used as-is.
2122            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2123            append: if `True`, add to any existing expressions.
2124                Otherwise, this resets the expressions.
2125            dialect: the dialect used to parse the input expression.
2126            copy: if `False`, modify this expression instance in-place.
2127            opts: other options to use to parse the input expressions.
2128
2129        Returns:
2130            The modified expression.
2131        """
2132        return _apply_cte_builder(
2133            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2134        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': True, '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:
2100    def with_(
2101        self,
2102        alias: ExpOrStr,
2103        as_: ExpOrStr,
2104        recursive: t.Optional[bool] = None,
2105        append: bool = True,
2106        dialect: DialectType = None,
2107        copy: bool = True,
2108        **opts,
2109    ) -> Insert:
2110        """
2111        Append to or set the common table expressions.
2112
2113        Example:
2114            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2115            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2116
2117        Args:
2118            alias: the SQL code string to parse as the table name.
2119                If an `Expression` instance is passed, this is used as-is.
2120            as_: the SQL code string to parse as the table expression.
2121                If an `Expression` instance is passed, it will be used as-is.
2122            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2123            append: if `True`, add to any existing expressions.
2124                Otherwise, this resets the expressions.
2125            dialect: the dialect used to parse the input expression.
2126            copy: if `False`, modify this expression instance in-place.
2127            opts: other options to use to parse the input expressions.
2128
2129        Returns:
2130            The modified expression.
2131        """
2132        return _apply_cte_builder(
2133            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2134        )

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):
2137class OnConflict(Expression):
2138    arg_types = {
2139        "duplicate": False,
2140        "expressions": False,
2141        "action": False,
2142        "conflict_keys": False,
2143        "constraint": False,
2144    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2147class Returning(Expression):
2148    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2152class Introducer(Expression):
2153    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2157class National(Expression):
2158    pass
key = 'national'
class LoadData(Expression):
2161class LoadData(Expression):
2162    arg_types = {
2163        "this": True,
2164        "local": False,
2165        "overwrite": False,
2166        "inpath": True,
2167        "partition": False,
2168        "input_format": False,
2169        "serde": False,
2170    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2173class Partition(Expression):
2174    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2177class PartitionRange(Expression):
2178    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
2181class Fetch(Expression):
2182    arg_types = {
2183        "direction": False,
2184        "count": False,
2185        "percent": False,
2186        "with_ties": False,
2187    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2190class Group(Expression):
2191    arg_types = {
2192        "expressions": False,
2193        "grouping_sets": False,
2194        "cube": False,
2195        "rollup": False,
2196        "totals": False,
2197        "all": False,
2198    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2201class Lambda(Expression):
2202    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2205class Limit(Expression):
2206    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):
2209class Literal(Condition):
2210    arg_types = {"this": True, "is_string": True}
2211
2212    @property
2213    def hashable_args(self) -> t.Any:
2214        return (self.this, self.args.get("is_string"))
2215
2216    @classmethod
2217    def number(cls, number) -> Literal:
2218        return cls(this=str(number), is_string=False)
2219
2220    @classmethod
2221    def string(cls, string) -> Literal:
2222        return cls(this=str(string), is_string=True)
2223
2224    @property
2225    def output_name(self) -> str:
2226        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2212    @property
2213    def hashable_args(self) -> t.Any:
2214        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2216    @classmethod
2217    def number(cls, number) -> Literal:
2218        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2220    @classmethod
2221    def string(cls, string) -> Literal:
2222        return cls(this=str(string), is_string=True)
output_name: str
2224    @property
2225    def output_name(self) -> str:
2226        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):
2229class Join(Expression):
2230    arg_types = {
2231        "this": True,
2232        "on": False,
2233        "side": False,
2234        "kind": False,
2235        "using": False,
2236        "method": False,
2237        "global": False,
2238        "hint": False,
2239        "match_condition": False,  # Snowflake
2240    }
2241
2242    @property
2243    def method(self) -> str:
2244        return self.text("method").upper()
2245
2246    @property
2247    def kind(self) -> str:
2248        return self.text("kind").upper()
2249
2250    @property
2251    def side(self) -> str:
2252        return self.text("side").upper()
2253
2254    @property
2255    def hint(self) -> str:
2256        return self.text("hint").upper()
2257
2258    @property
2259    def alias_or_name(self) -> str:
2260        return self.this.alias_or_name
2261
2262    def on(
2263        self,
2264        *expressions: t.Optional[ExpOrStr],
2265        append: bool = True,
2266        dialect: DialectType = None,
2267        copy: bool = True,
2268        **opts,
2269    ) -> Join:
2270        """
2271        Append to or set the ON expressions.
2272
2273        Example:
2274            >>> import sqlglot
2275            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2276            'JOIN x ON y = 1'
2277
2278        Args:
2279            *expressions: the SQL code strings to parse.
2280                If an `Expression` instance is passed, it will be used as-is.
2281                Multiple expressions are combined with an AND operator.
2282            append: if `True`, AND the new expressions to any existing expression.
2283                Otherwise, this resets the expression.
2284            dialect: the dialect used to parse the input expressions.
2285            copy: if `False`, modify this expression instance in-place.
2286            opts: other options to use to parse the input expressions.
2287
2288        Returns:
2289            The modified Join expression.
2290        """
2291        join = _apply_conjunction_builder(
2292            *expressions,
2293            instance=self,
2294            arg="on",
2295            append=append,
2296            dialect=dialect,
2297            copy=copy,
2298            **opts,
2299        )
2300
2301        if join.kind == "CROSS":
2302            join.set("kind", None)
2303
2304        return join
2305
2306    def using(
2307        self,
2308        *expressions: t.Optional[ExpOrStr],
2309        append: bool = True,
2310        dialect: DialectType = None,
2311        copy: bool = True,
2312        **opts,
2313    ) -> Join:
2314        """
2315        Append to or set the USING expressions.
2316
2317        Example:
2318            >>> import sqlglot
2319            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2320            'JOIN x USING (foo, bla)'
2321
2322        Args:
2323            *expressions: the SQL code strings to parse.
2324                If an `Expression` instance is passed, it will be used as-is.
2325            append: if `True`, concatenate the new expressions to the existing "using" list.
2326                Otherwise, this resets the expression.
2327            dialect: the dialect used to parse the input expressions.
2328            copy: if `False`, modify this expression instance in-place.
2329            opts: other options to use to parse the input expressions.
2330
2331        Returns:
2332            The modified Join expression.
2333        """
2334        join = _apply_list_builder(
2335            *expressions,
2336            instance=self,
2337            arg="using",
2338            append=append,
2339            dialect=dialect,
2340            copy=copy,
2341            **opts,
2342        )
2343
2344        if join.kind == "CROSS":
2345            join.set("kind", None)
2346
2347        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
2242    @property
2243    def method(self) -> str:
2244        return self.text("method").upper()
kind: str
2246    @property
2247    def kind(self) -> str:
2248        return self.text("kind").upper()
side: str
2250    @property
2251    def side(self) -> str:
2252        return self.text("side").upper()
hint: str
2254    @property
2255    def hint(self) -> str:
2256        return self.text("hint").upper()
alias_or_name: str
2258    @property
2259    def alias_or_name(self) -> str:
2260        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:
2262    def on(
2263        self,
2264        *expressions: t.Optional[ExpOrStr],
2265        append: bool = True,
2266        dialect: DialectType = None,
2267        copy: bool = True,
2268        **opts,
2269    ) -> Join:
2270        """
2271        Append to or set the ON expressions.
2272
2273        Example:
2274            >>> import sqlglot
2275            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2276            'JOIN x ON y = 1'
2277
2278        Args:
2279            *expressions: the SQL code strings to parse.
2280                If an `Expression` instance is passed, it will be used as-is.
2281                Multiple expressions are combined with an AND operator.
2282            append: if `True`, AND the new expressions to any existing expression.
2283                Otherwise, this resets the expression.
2284            dialect: the dialect used to parse the input expressions.
2285            copy: if `False`, modify this expression instance in-place.
2286            opts: other options to use to parse the input expressions.
2287
2288        Returns:
2289            The modified Join expression.
2290        """
2291        join = _apply_conjunction_builder(
2292            *expressions,
2293            instance=self,
2294            arg="on",
2295            append=append,
2296            dialect=dialect,
2297            copy=copy,
2298            **opts,
2299        )
2300
2301        if join.kind == "CROSS":
2302            join.set("kind", None)
2303
2304        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:
2306    def using(
2307        self,
2308        *expressions: t.Optional[ExpOrStr],
2309        append: bool = True,
2310        dialect: DialectType = None,
2311        copy: bool = True,
2312        **opts,
2313    ) -> Join:
2314        """
2315        Append to or set the USING expressions.
2316
2317        Example:
2318            >>> import sqlglot
2319            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2320            'JOIN x USING (foo, bla)'
2321
2322        Args:
2323            *expressions: the SQL code strings to parse.
2324                If an `Expression` instance is passed, it will be used as-is.
2325            append: if `True`, concatenate the new expressions to the existing "using" list.
2326                Otherwise, this resets the expression.
2327            dialect: the dialect used to parse the input expressions.
2328            copy: if `False`, modify this expression instance in-place.
2329            opts: other options to use to parse the input expressions.
2330
2331        Returns:
2332            The modified Join expression.
2333        """
2334        join = _apply_list_builder(
2335            *expressions,
2336            instance=self,
2337            arg="using",
2338            append=append,
2339            dialect=dialect,
2340            copy=copy,
2341            **opts,
2342        )
2343
2344        if join.kind == "CROSS":
2345            join.set("kind", None)
2346
2347        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):
2350class Lateral(UDTF):
2351    arg_types = {
2352        "this": True,
2353        "view": False,
2354        "outer": False,
2355        "alias": False,
2356        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2357    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2360class MatchRecognizeMeasure(Expression):
2361    arg_types = {
2362        "this": True,
2363        "window_frame": False,
2364    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2367class MatchRecognize(Expression):
2368    arg_types = {
2369        "partition_by": False,
2370        "order": False,
2371        "measures": False,
2372        "rows": False,
2373        "after": False,
2374        "pattern": False,
2375        "define": False,
2376        "alias": False,
2377    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2382class Final(Expression):
2383    pass
key = 'final'
class Offset(Expression):
2386class Offset(Expression):
2387    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2390class Order(Expression):
2391    arg_types = {
2392        "this": False,
2393        "expressions": True,
2394        "interpolate": False,
2395        "siblings": False,
2396    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2400class WithFill(Expression):
2401    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2406class Cluster(Order):
2407    pass
key = 'cluster'
class Distribute(Order):
2410class Distribute(Order):
2411    pass
key = 'distribute'
class Sort(Order):
2414class Sort(Order):
2415    pass
key = 'sort'
class Ordered(Expression):
2418class Ordered(Expression):
2419    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):
2422class Property(Expression):
2423    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2426class AlgorithmProperty(Property):
2427    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2430class AutoIncrementProperty(Property):
2431    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2435class AutoRefreshProperty(Property):
2436    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2439class BackupProperty(Property):
2440    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2443class BlockCompressionProperty(Property):
2444    arg_types = {
2445        "autotemp": False,
2446        "always": False,
2447        "default": False,
2448        "manual": False,
2449        "never": False,
2450    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2453class CharacterSetProperty(Property):
2454    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2457class ChecksumProperty(Property):
2458    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2461class CollateProperty(Property):
2462    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2465class CopyGrantsProperty(Property):
2466    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2469class DataBlocksizeProperty(Property):
2470    arg_types = {
2471        "size": False,
2472        "units": False,
2473        "minimum": False,
2474        "maximum": False,
2475        "default": False,
2476    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2479class DefinerProperty(Property):
2480    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2483class DistKeyProperty(Property):
2484    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2487class DistStyleProperty(Property):
2488    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2491class EngineProperty(Property):
2492    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2495class HeapProperty(Property):
2496    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2499class ToTableProperty(Property):
2500    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2503class ExecuteAsProperty(Property):
2504    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2507class ExternalProperty(Property):
2508    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2511class FallbackProperty(Property):
2512    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2515class FileFormatProperty(Property):
2516    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2519class FreespaceProperty(Property):
2520    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2523class GlobalProperty(Property):
2524    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2527class IcebergProperty(Property):
2528    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2531class InheritsProperty(Property):
2532    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2535class InputModelProperty(Property):
2536    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2539class OutputModelProperty(Property):
2540    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2543class IsolatedLoadingProperty(Property):
2544    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2547class JournalProperty(Property):
2548    arg_types = {
2549        "no": False,
2550        "dual": False,
2551        "before": False,
2552        "local": False,
2553        "after": False,
2554    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2557class LanguageProperty(Property):
2558    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2562class ClusteredByProperty(Property):
2563    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2566class DictProperty(Property):
2567    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2570class DictSubProperty(Property):
2571    pass
key = 'dictsubproperty'
class DictRange(Property):
2574class DictRange(Property):
2575    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2580class OnCluster(Property):
2581    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2584class LikeProperty(Property):
2585    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2588class LocationProperty(Property):
2589    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2592class LockProperty(Property):
2593    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2596class LockingProperty(Property):
2597    arg_types = {
2598        "this": False,
2599        "kind": True,
2600        "for_or_in": False,
2601        "lock_type": True,
2602        "override": False,
2603    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2606class LogProperty(Property):
2607    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2610class MaterializedProperty(Property):
2611    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2614class MergeBlockRatioProperty(Property):
2615    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):
2618class NoPrimaryIndexProperty(Property):
2619    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2622class OnProperty(Property):
2623    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2626class OnCommitProperty(Property):
2627    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2630class PartitionedByProperty(Property):
2631    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2635class PartitionBoundSpec(Expression):
2636    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2637    arg_types = {
2638        "this": False,
2639        "expression": False,
2640        "from_expressions": False,
2641        "to_expressions": False,
2642    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2645class PartitionedOfProperty(Property):
2646    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2647    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2650class RemoteWithConnectionModelProperty(Property):
2651    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2654class ReturnsProperty(Property):
2655    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2658class RowFormatProperty(Property):
2659    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2662class RowFormatDelimitedProperty(Property):
2663    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2664    arg_types = {
2665        "fields": False,
2666        "escaped": False,
2667        "collection_items": False,
2668        "map_keys": False,
2669        "lines": False,
2670        "null": False,
2671        "serde": False,
2672    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2675class RowFormatSerdeProperty(Property):
2676    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2680class QueryTransform(Expression):
2681    arg_types = {
2682        "expressions": True,
2683        "command_script": True,
2684        "schema": False,
2685        "row_format_before": False,
2686        "record_writer": False,
2687        "row_format_after": False,
2688        "record_reader": False,
2689    }
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):
2692class SampleProperty(Property):
2693    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2696class SchemaCommentProperty(Property):
2697    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2700class SerdeProperties(Property):
2701    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2704class SetProperty(Property):
2705    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2708class SharingProperty(Property):
2709    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2712class SetConfigProperty(Property):
2713    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2716class SettingsProperty(Property):
2717    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2720class SortKeyProperty(Property):
2721    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2724class SqlReadWriteProperty(Property):
2725    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2728class SqlSecurityProperty(Property):
2729    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2732class StabilityProperty(Property):
2733    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2736class TemporaryProperty(Property):
2737    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2740class TransformModelProperty(Property):
2741    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2744class TransientProperty(Property):
2745    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2748class UnloggedProperty(Property):
2749    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2753class ViewAttributeProperty(Property):
2754    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2757class VolatileProperty(Property):
2758    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2761class WithDataProperty(Property):
2762    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2765class WithJournalTableProperty(Property):
2766    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2769class WithSystemVersioningProperty(Property):
2770    # this -> history table name, expression -> data consistency check
2771    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2774class Properties(Expression):
2775    arg_types = {"expressions": True}
2776
2777    NAME_TO_PROPERTY = {
2778        "ALGORITHM": AlgorithmProperty,
2779        "AUTO_INCREMENT": AutoIncrementProperty,
2780        "CHARACTER SET": CharacterSetProperty,
2781        "CLUSTERED_BY": ClusteredByProperty,
2782        "COLLATE": CollateProperty,
2783        "COMMENT": SchemaCommentProperty,
2784        "DEFINER": DefinerProperty,
2785        "DISTKEY": DistKeyProperty,
2786        "DISTSTYLE": DistStyleProperty,
2787        "ENGINE": EngineProperty,
2788        "EXECUTE AS": ExecuteAsProperty,
2789        "FORMAT": FileFormatProperty,
2790        "LANGUAGE": LanguageProperty,
2791        "LOCATION": LocationProperty,
2792        "LOCK": LockProperty,
2793        "PARTITIONED_BY": PartitionedByProperty,
2794        "RETURNS": ReturnsProperty,
2795        "ROW_FORMAT": RowFormatProperty,
2796        "SORTKEY": SortKeyProperty,
2797    }
2798
2799    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2800
2801    # CREATE property locations
2802    # Form: schema specified
2803    #   create [POST_CREATE]
2804    #     table a [POST_NAME]
2805    #     (b int) [POST_SCHEMA]
2806    #     with ([POST_WITH])
2807    #     index (b) [POST_INDEX]
2808    #
2809    # Form: alias selection
2810    #   create [POST_CREATE]
2811    #     table a [POST_NAME]
2812    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2813    #     index (c) [POST_INDEX]
2814    class Location(AutoName):
2815        POST_CREATE = auto()
2816        POST_NAME = auto()
2817        POST_SCHEMA = auto()
2818        POST_WITH = auto()
2819        POST_ALIAS = auto()
2820        POST_EXPRESSION = auto()
2821        POST_INDEX = auto()
2822        UNSUPPORTED = auto()
2823
2824    @classmethod
2825    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2826        expressions = []
2827        for key, value in properties_dict.items():
2828            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2829            if property_cls:
2830                expressions.append(property_cls(this=convert(value)))
2831            else:
2832                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2833
2834        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:
2824    @classmethod
2825    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2826        expressions = []
2827        for key, value in properties_dict.items():
2828            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2829            if property_cls:
2830                expressions.append(property_cls(this=convert(value)))
2831            else:
2832                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2833
2834        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2814    class Location(AutoName):
2815        POST_CREATE = auto()
2816        POST_NAME = auto()
2817        POST_SCHEMA = auto()
2818        POST_WITH = auto()
2819        POST_ALIAS = auto()
2820        POST_EXPRESSION = auto()
2821        POST_INDEX = auto()
2822        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):
2837class Qualify(Expression):
2838    pass
key = 'qualify'
class InputOutputFormat(Expression):
2841class InputOutputFormat(Expression):
2842    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2846class Return(Expression):
2847    pass
key = 'return'
class Reference(Expression):
2850class Reference(Expression):
2851    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2854class Tuple(Expression):
2855    arg_types = {"expressions": False}
2856
2857    def isin(
2858        self,
2859        *expressions: t.Any,
2860        query: t.Optional[ExpOrStr] = None,
2861        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2862        copy: bool = True,
2863        **opts,
2864    ) -> In:
2865        return In(
2866            this=maybe_copy(self, copy),
2867            expressions=[convert(e, copy=copy) for e in expressions],
2868            query=maybe_parse(query, copy=copy, **opts) if query else None,
2869            unnest=(
2870                Unnest(
2871                    expressions=[
2872                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2873                        for e in ensure_list(unnest)
2874                    ]
2875                )
2876                if unnest
2877                else None
2878            ),
2879        )
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:
2857    def isin(
2858        self,
2859        *expressions: t.Any,
2860        query: t.Optional[ExpOrStr] = None,
2861        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2862        copy: bool = True,
2863        **opts,
2864    ) -> In:
2865        return In(
2866            this=maybe_copy(self, copy),
2867            expressions=[convert(e, copy=copy) for e in expressions],
2868            query=maybe_parse(query, copy=copy, **opts) if query else None,
2869            unnest=(
2870                Unnest(
2871                    expressions=[
2872                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2873                        for e in ensure_list(unnest)
2874                    ]
2875                )
2876                if unnest
2877                else None
2878            ),
2879        )
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):
2910class QueryOption(Expression):
2911    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2915class WithTableHint(Expression):
2916    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2920class IndexTableHint(Expression):
2921    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2925class HistoricalData(Expression):
2926    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2929class Table(Expression):
2930    arg_types = {
2931        "this": False,
2932        "alias": False,
2933        "db": False,
2934        "catalog": False,
2935        "laterals": False,
2936        "joins": False,
2937        "pivots": False,
2938        "hints": False,
2939        "system_time": False,
2940        "version": False,
2941        "format": False,
2942        "pattern": False,
2943        "ordinality": False,
2944        "when": False,
2945        "only": False,
2946        "partition": False,
2947    }
2948
2949    @property
2950    def name(self) -> str:
2951        if isinstance(self.this, Func):
2952            return ""
2953        return self.this.name
2954
2955    @property
2956    def db(self) -> str:
2957        return self.text("db")
2958
2959    @property
2960    def catalog(self) -> str:
2961        return self.text("catalog")
2962
2963    @property
2964    def selects(self) -> t.List[Expression]:
2965        return []
2966
2967    @property
2968    def named_selects(self) -> t.List[str]:
2969        return []
2970
2971    @property
2972    def parts(self) -> t.List[Expression]:
2973        """Return the parts of a table in order catalog, db, table."""
2974        parts: t.List[Expression] = []
2975
2976        for arg in ("catalog", "db", "this"):
2977            part = self.args.get(arg)
2978
2979            if isinstance(part, Dot):
2980                parts.extend(part.flatten())
2981            elif isinstance(part, Expression):
2982                parts.append(part)
2983
2984        return parts
2985
2986    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2987        parts = self.parts
2988        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2989        alias = self.args.get("alias")
2990        if alias:
2991            col = alias_(col, alias.this, copy=copy)
2992        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
2949    @property
2950    def name(self) -> str:
2951        if isinstance(self.this, Func):
2952            return ""
2953        return self.this.name
db: str
2955    @property
2956    def db(self) -> str:
2957        return self.text("db")
catalog: str
2959    @property
2960    def catalog(self) -> str:
2961        return self.text("catalog")
selects: List[Expression]
2963    @property
2964    def selects(self) -> t.List[Expression]:
2965        return []
named_selects: List[str]
2967    @property
2968    def named_selects(self) -> t.List[str]:
2969        return []
parts: List[Expression]
2971    @property
2972    def parts(self) -> t.List[Expression]:
2973        """Return the parts of a table in order catalog, db, table."""
2974        parts: t.List[Expression] = []
2975
2976        for arg in ("catalog", "db", "this"):
2977            part = self.args.get(arg)
2978
2979            if isinstance(part, Dot):
2980                parts.extend(part.flatten())
2981            elif isinstance(part, Expression):
2982                parts.append(part)
2983
2984        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2986    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2987        parts = self.parts
2988        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2989        alias = self.args.get("alias")
2990        if alias:
2991            col = alias_(col, alias.this, copy=copy)
2992        return col
key = 'table'
class Union(Query):
2995class Union(Query):
2996    arg_types = {
2997        "with": False,
2998        "this": True,
2999        "expression": True,
3000        "distinct": False,
3001        "by_name": False,
3002        **QUERY_MODIFIERS,
3003    }
3004
3005    def select(
3006        self,
3007        *expressions: t.Optional[ExpOrStr],
3008        append: bool = True,
3009        dialect: DialectType = None,
3010        copy: bool = True,
3011        **opts,
3012    ) -> Union:
3013        this = maybe_copy(self, copy)
3014        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3015        this.expression.unnest().select(
3016            *expressions, append=append, dialect=dialect, copy=False, **opts
3017        )
3018        return this
3019
3020    @property
3021    def named_selects(self) -> t.List[str]:
3022        return self.this.unnest().named_selects
3023
3024    @property
3025    def is_star(self) -> bool:
3026        return self.this.is_star or self.expression.is_star
3027
3028    @property
3029    def selects(self) -> t.List[Expression]:
3030        return self.this.unnest().selects
3031
3032    @property
3033    def left(self) -> Expression:
3034        return self.this
3035
3036    @property
3037    def right(self) -> Expression:
3038        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:
3005    def select(
3006        self,
3007        *expressions: t.Optional[ExpOrStr],
3008        append: bool = True,
3009        dialect: DialectType = None,
3010        copy: bool = True,
3011        **opts,
3012    ) -> Union:
3013        this = maybe_copy(self, copy)
3014        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3015        this.expression.unnest().select(
3016            *expressions, append=append, dialect=dialect, copy=False, **opts
3017        )
3018        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]
3020    @property
3021    def named_selects(self) -> t.List[str]:
3022        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3024    @property
3025    def is_star(self) -> bool:
3026        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3028    @property
3029    def selects(self) -> t.List[Expression]:
3030        return self.this.unnest().selects

Returns the query's projections.

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

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:
3154    def group_by(
3155        self,
3156        *expressions: t.Optional[ExpOrStr],
3157        append: bool = True,
3158        dialect: DialectType = None,
3159        copy: bool = True,
3160        **opts,
3161    ) -> Select:
3162        """
3163        Set the GROUP BY expression.
3164
3165        Example:
3166            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3167            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3168
3169        Args:
3170            *expressions: the SQL code strings to parse.
3171                If a `Group` instance is passed, this is used as-is.
3172                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3173                If nothing is passed in then a group by is not applied to the expression
3174            append: if `True`, add to any existing expressions.
3175                Otherwise, this flattens all the `Group` expression into a single expression.
3176            dialect: the dialect used to parse the input expression.
3177            copy: if `False`, modify this expression instance in-place.
3178            opts: other options to use to parse the input expressions.
3179
3180        Returns:
3181            The modified Select expression.
3182        """
3183        if not expressions:
3184            return self if not copy else self.copy()
3185
3186        return _apply_child_list_builder(
3187            *expressions,
3188            instance=self,
3189            arg="group",
3190            append=append,
3191            copy=copy,
3192            prefix="GROUP BY",
3193            into=Group,
3194            dialect=dialect,
3195            **opts,
3196        )

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:
3198    def sort_by(
3199        self,
3200        *expressions: t.Optional[ExpOrStr],
3201        append: bool = True,
3202        dialect: DialectType = None,
3203        copy: bool = True,
3204        **opts,
3205    ) -> Select:
3206        """
3207        Set the SORT BY expression.
3208
3209        Example:
3210            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3211            'SELECT x FROM tbl SORT BY x DESC'
3212
3213        Args:
3214            *expressions: the SQL code strings to parse.
3215                If a `Group` instance is passed, this is used as-is.
3216                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3217            append: if `True`, add to any existing expressions.
3218                Otherwise, this flattens all the `Order` expression into a single expression.
3219            dialect: the dialect used to parse the input expression.
3220            copy: if `False`, modify this expression instance in-place.
3221            opts: other options to use to parse the input expressions.
3222
3223        Returns:
3224            The modified Select expression.
3225        """
3226        return _apply_child_list_builder(
3227            *expressions,
3228            instance=self,
3229            arg="sort",
3230            append=append,
3231            copy=copy,
3232            prefix="SORT BY",
3233            into=Sort,
3234            dialect=dialect,
3235            **opts,
3236        )

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

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:
3278    def select(
3279        self,
3280        *expressions: t.Optional[ExpOrStr],
3281        append: bool = True,
3282        dialect: DialectType = None,
3283        copy: bool = True,
3284        **opts,
3285    ) -> Select:
3286        return _apply_list_builder(
3287            *expressions,
3288            instance=self,
3289            arg="expressions",
3290            append=append,
3291            dialect=dialect,
3292            into=Expression,
3293            copy=copy,
3294            **opts,
3295        )

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:
3297    def lateral(
3298        self,
3299        *expressions: t.Optional[ExpOrStr],
3300        append: bool = True,
3301        dialect: DialectType = None,
3302        copy: bool = True,
3303        **opts,
3304    ) -> Select:
3305        """
3306        Append to or set the LATERAL expressions.
3307
3308        Example:
3309            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3310            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3311
3312        Args:
3313            *expressions: the SQL code strings to parse.
3314                If an `Expression` instance is passed, it will be used as-is.
3315            append: if `True`, add to any existing expressions.
3316                Otherwise, this resets the expressions.
3317            dialect: the dialect used to parse the input expressions.
3318            copy: if `False`, modify this expression instance in-place.
3319            opts: other options to use to parse the input expressions.
3320
3321        Returns:
3322            The modified Select expression.
3323        """
3324        return _apply_list_builder(
3325            *expressions,
3326            instance=self,
3327            arg="laterals",
3328            append=append,
3329            into=Lateral,
3330            prefix="LATERAL VIEW",
3331            dialect=dialect,
3332            copy=copy,
3333            **opts,
3334        )

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:
3336    def join(
3337        self,
3338        expression: ExpOrStr,
3339        on: t.Optional[ExpOrStr] = None,
3340        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3341        append: bool = True,
3342        join_type: t.Optional[str] = None,
3343        join_alias: t.Optional[Identifier | str] = None,
3344        dialect: DialectType = None,
3345        copy: bool = True,
3346        **opts,
3347    ) -> Select:
3348        """
3349        Append to or set the JOIN expressions.
3350
3351        Example:
3352            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3353            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3354
3355            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3356            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3357
3358            Use `join_type` to change the type of join:
3359
3360            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3361            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3362
3363        Args:
3364            expression: the SQL code string to parse.
3365                If an `Expression` instance is passed, it will be used as-is.
3366            on: optionally specify the join "on" criteria as a SQL string.
3367                If an `Expression` instance is passed, it will be used as-is.
3368            using: optionally specify the join "using" criteria as a SQL string.
3369                If an `Expression` instance is passed, it will be used as-is.
3370            append: if `True`, add to any existing expressions.
3371                Otherwise, this resets the expressions.
3372            join_type: if set, alter the parsed join type.
3373            join_alias: an optional alias for the joined source.
3374            dialect: the dialect used to parse the input expressions.
3375            copy: if `False`, modify this expression instance in-place.
3376            opts: other options to use to parse the input expressions.
3377
3378        Returns:
3379            Select: the modified expression.
3380        """
3381        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3382
3383        try:
3384            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3385        except ParseError:
3386            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3387
3388        join = expression if isinstance(expression, Join) else Join(this=expression)
3389
3390        if isinstance(join.this, Select):
3391            join.this.replace(join.this.subquery())
3392
3393        if join_type:
3394            method: t.Optional[Token]
3395            side: t.Optional[Token]
3396            kind: t.Optional[Token]
3397
3398            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3399
3400            if method:
3401                join.set("method", method.text)
3402            if side:
3403                join.set("side", side.text)
3404            if kind:
3405                join.set("kind", kind.text)
3406
3407        if on:
3408            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3409            join.set("on", on)
3410
3411        if using:
3412            join = _apply_list_builder(
3413                *ensure_list(using),
3414                instance=join,
3415                arg="using",
3416                append=append,
3417                copy=copy,
3418                into=Identifier,
3419                **opts,
3420            )
3421
3422        if join_alias:
3423            join.set("this", alias_(join.this, join_alias, table=True))
3424
3425        return _apply_list_builder(
3426            join,
3427            instance=self,
3428            arg="joins",
3429            append=append,
3430            copy=copy,
3431            **opts,
3432        )

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:
3434    def where(
3435        self,
3436        *expressions: t.Optional[ExpOrStr],
3437        append: bool = True,
3438        dialect: DialectType = None,
3439        copy: bool = True,
3440        **opts,
3441    ) -> Select:
3442        """
3443        Append to or set the WHERE expressions.
3444
3445        Example:
3446            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3447            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3448
3449        Args:
3450            *expressions: the SQL code strings to parse.
3451                If an `Expression` instance is passed, it will be used as-is.
3452                Multiple expressions are combined with an AND operator.
3453            append: if `True`, AND the new expressions to any existing expression.
3454                Otherwise, this resets the expression.
3455            dialect: the dialect used to parse the input expressions.
3456            copy: if `False`, modify this expression instance in-place.
3457            opts: other options to use to parse the input expressions.
3458
3459        Returns:
3460            Select: the modified expression.
3461        """
3462        return _apply_conjunction_builder(
3463            *expressions,
3464            instance=self,
3465            arg="where",
3466            append=append,
3467            into=Where,
3468            dialect=dialect,
3469            copy=copy,
3470            **opts,
3471        )

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:
3473    def having(
3474        self,
3475        *expressions: t.Optional[ExpOrStr],
3476        append: bool = True,
3477        dialect: DialectType = None,
3478        copy: bool = True,
3479        **opts,
3480    ) -> Select:
3481        """
3482        Append to or set the HAVING expressions.
3483
3484        Example:
3485            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3486            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3487
3488        Args:
3489            *expressions: the SQL code strings to parse.
3490                If an `Expression` instance is passed, it will be used as-is.
3491                Multiple expressions are combined with an AND operator.
3492            append: if `True`, AND the new expressions to any existing expression.
3493                Otherwise, this resets the expression.
3494            dialect: the dialect used to parse the input expressions.
3495            copy: if `False`, modify this expression instance in-place.
3496            opts: other options to use to parse the input expressions.
3497
3498        Returns:
3499            The modified Select expression.
3500        """
3501        return _apply_conjunction_builder(
3502            *expressions,
3503            instance=self,
3504            arg="having",
3505            append=append,
3506            into=Having,
3507            dialect=dialect,
3508            copy=copy,
3509            **opts,
3510        )

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:
3512    def window(
3513        self,
3514        *expressions: t.Optional[ExpOrStr],
3515        append: bool = True,
3516        dialect: DialectType = None,
3517        copy: bool = True,
3518        **opts,
3519    ) -> Select:
3520        return _apply_list_builder(
3521            *expressions,
3522            instance=self,
3523            arg="windows",
3524            append=append,
3525            into=Window,
3526            dialect=dialect,
3527            copy=copy,
3528            **opts,
3529        )
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:
3531    def qualify(
3532        self,
3533        *expressions: t.Optional[ExpOrStr],
3534        append: bool = True,
3535        dialect: DialectType = None,
3536        copy: bool = True,
3537        **opts,
3538    ) -> Select:
3539        return _apply_conjunction_builder(
3540            *expressions,
3541            instance=self,
3542            arg="qualify",
3543            append=append,
3544            into=Qualify,
3545            dialect=dialect,
3546            copy=copy,
3547            **opts,
3548        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3550    def distinct(
3551        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3552    ) -> Select:
3553        """
3554        Set the OFFSET expression.
3555
3556        Example:
3557            >>> Select().from_("tbl").select("x").distinct().sql()
3558            'SELECT DISTINCT x FROM tbl'
3559
3560        Args:
3561            ons: the expressions to distinct on
3562            distinct: whether the Select should be distinct
3563            copy: if `False`, modify this expression instance in-place.
3564
3565        Returns:
3566            Select: the modified expression.
3567        """
3568        instance = maybe_copy(self, copy)
3569        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3570        instance.set("distinct", Distinct(on=on) if distinct else None)
3571        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:
3573    def ctas(
3574        self,
3575        table: ExpOrStr,
3576        properties: t.Optional[t.Dict] = None,
3577        dialect: DialectType = None,
3578        copy: bool = True,
3579        **opts,
3580    ) -> Create:
3581        """
3582        Convert this expression to a CREATE TABLE AS statement.
3583
3584        Example:
3585            >>> Select().select("*").from_("tbl").ctas("x").sql()
3586            'CREATE TABLE x AS SELECT * FROM tbl'
3587
3588        Args:
3589            table: the SQL code string to parse as the table name.
3590                If another `Expression` instance is passed, it will be used as-is.
3591            properties: an optional mapping of table properties
3592            dialect: the dialect used to parse the input table.
3593            copy: if `False`, modify this expression instance in-place.
3594            opts: other options to use to parse the input table.
3595
3596        Returns:
3597            The new Create expression.
3598        """
3599        instance = maybe_copy(self, copy)
3600        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3601
3602        properties_expression = None
3603        if properties:
3604            properties_expression = Properties.from_dict(properties)
3605
3606        return Create(
3607            this=table_expression,
3608            kind="TABLE",
3609            expression=instance,
3610            properties=properties_expression,
3611        )

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:
3613    def lock(self, update: bool = True, copy: bool = True) -> Select:
3614        """
3615        Set the locking read mode for this expression.
3616
3617        Examples:
3618            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3619            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3620
3621            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3622            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3623
3624        Args:
3625            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3626            copy: if `False`, modify this expression instance in-place.
3627
3628        Returns:
3629            The modified expression.
3630        """
3631        inst = maybe_copy(self, copy)
3632        inst.set("locks", [Lock(update=update)])
3633
3634        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:
3636    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3637        """
3638        Set hints for this expression.
3639
3640        Examples:
3641            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3642            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3643
3644        Args:
3645            hints: The SQL code strings to parse as the hints.
3646                If an `Expression` instance is passed, it will be used as-is.
3647            dialect: The dialect used to parse the hints.
3648            copy: If `False`, modify this expression instance in-place.
3649
3650        Returns:
3651            The modified expression.
3652        """
3653        inst = maybe_copy(self, copy)
3654        inst.set(
3655            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3656        )
3657
3658        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]
3660    @property
3661    def named_selects(self) -> t.List[str]:
3662        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
3664    @property
3665    def is_star(self) -> bool:
3666        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3668    @property
3669    def selects(self) -> t.List[Expression]:
3670        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3676class Subquery(DerivedTable, Query):
3677    arg_types = {
3678        "this": True,
3679        "alias": False,
3680        "with": False,
3681        **QUERY_MODIFIERS,
3682    }
3683
3684    def unnest(self):
3685        """Returns the first non subquery."""
3686        expression = self
3687        while isinstance(expression, Subquery):
3688            expression = expression.this
3689        return expression
3690
3691    def unwrap(self) -> Subquery:
3692        expression = self
3693        while expression.same_parent and expression.is_wrapper:
3694            expression = t.cast(Subquery, expression.parent)
3695        return expression
3696
3697    def select(
3698        self,
3699        *expressions: t.Optional[ExpOrStr],
3700        append: bool = True,
3701        dialect: DialectType = None,
3702        copy: bool = True,
3703        **opts,
3704    ) -> Subquery:
3705        this = maybe_copy(self, copy)
3706        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3707        return this
3708
3709    @property
3710    def is_wrapper(self) -> bool:
3711        """
3712        Whether this Subquery acts as a simple wrapper around another expression.
3713
3714        SELECT * FROM (((SELECT * FROM t)))
3715                      ^
3716                      This corresponds to a "wrapper" Subquery node
3717        """
3718        return all(v is None for k, v in self.args.items() if k != "this")
3719
3720    @property
3721    def is_star(self) -> bool:
3722        return self.this.is_star
3723
3724    @property
3725    def output_name(self) -> str:
3726        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):
3684    def unnest(self):
3685        """Returns the first non subquery."""
3686        expression = self
3687        while isinstance(expression, Subquery):
3688            expression = expression.this
3689        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3691    def unwrap(self) -> Subquery:
3692        expression = self
3693        while expression.same_parent and expression.is_wrapper:
3694            expression = t.cast(Subquery, expression.parent)
3695        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:
3697    def select(
3698        self,
3699        *expressions: t.Optional[ExpOrStr],
3700        append: bool = True,
3701        dialect: DialectType = None,
3702        copy: bool = True,
3703        **opts,
3704    ) -> Subquery:
3705        this = maybe_copy(self, copy)
3706        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3707        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
3709    @property
3710    def is_wrapper(self) -> bool:
3711        """
3712        Whether this Subquery acts as a simple wrapper around another expression.
3713
3714        SELECT * FROM (((SELECT * FROM t)))
3715                      ^
3716                      This corresponds to a "wrapper" Subquery node
3717        """
3718        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
3720    @property
3721    def is_star(self) -> bool:
3722        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3724    @property
3725    def output_name(self) -> str:
3726        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):
3729class TableSample(Expression):
3730    arg_types = {
3731        "this": False,
3732        "expressions": False,
3733        "method": False,
3734        "bucket_numerator": False,
3735        "bucket_denominator": False,
3736        "bucket_field": False,
3737        "percent": False,
3738        "rows": False,
3739        "size": False,
3740        "seed": False,
3741    }
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):
3744class Tag(Expression):
3745    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3746
3747    arg_types = {
3748        "this": False,
3749        "prefix": False,
3750        "postfix": False,
3751    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3756class Pivot(Expression):
3757    arg_types = {
3758        "this": False,
3759        "alias": False,
3760        "expressions": False,
3761        "field": False,
3762        "unpivot": False,
3763        "using": False,
3764        "group": False,
3765        "columns": False,
3766        "include_nulls": False,
3767    }
3768
3769    @property
3770    def unpivot(self) -> bool:
3771        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
3769    @property
3770    def unpivot(self) -> bool:
3771        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3774class Window(Condition):
3775    arg_types = {
3776        "this": True,
3777        "partition_by": False,
3778        "order": False,
3779        "spec": False,
3780        "alias": False,
3781        "over": False,
3782        "first": False,
3783    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3786class WindowSpec(Expression):
3787    arg_types = {
3788        "kind": False,
3789        "start": False,
3790        "start_side": False,
3791        "end": False,
3792        "end_side": False,
3793    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3796class PreWhere(Expression):
3797    pass
key = 'prewhere'
class Where(Expression):
3800class Where(Expression):
3801    pass
key = 'where'
class Star(Expression):
3804class Star(Expression):
3805    arg_types = {"except": False, "replace": False}
3806
3807    @property
3808    def name(self) -> str:
3809        return "*"
3810
3811    @property
3812    def output_name(self) -> str:
3813        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3807    @property
3808    def name(self) -> str:
3809        return "*"
output_name: str
3811    @property
3812    def output_name(self) -> str:
3813        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):
3816class Parameter(Condition):
3817    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3820class SessionParameter(Condition):
3821    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3824class Placeholder(Condition):
3825    arg_types = {"this": False, "kind": False}
3826
3827    @property
3828    def name(self) -> str:
3829        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3827    @property
3828    def name(self) -> str:
3829        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3832class Null(Condition):
3833    arg_types: t.Dict[str, t.Any] = {}
3834
3835    @property
3836    def name(self) -> str:
3837        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3835    @property
3836    def name(self) -> str:
3837        return "NULL"
key = 'null'
class Boolean(Condition):
3840class Boolean(Condition):
3841    pass
key = 'boolean'
class DataTypeParam(Expression):
3844class DataTypeParam(Expression):
3845    arg_types = {"this": True, "expression": False}
3846
3847    @property
3848    def name(self) -> str:
3849        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3847    @property
3848    def name(self) -> str:
3849        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3852class DataType(Expression):
3853    arg_types = {
3854        "this": True,
3855        "expressions": False,
3856        "nested": False,
3857        "values": False,
3858        "prefix": False,
3859        "kind": False,
3860    }
3861
3862    class Type(AutoName):
3863        ARRAY = auto()
3864        AGGREGATEFUNCTION = auto()
3865        SIMPLEAGGREGATEFUNCTION = auto()
3866        BIGDECIMAL = auto()
3867        BIGINT = auto()
3868        BIGSERIAL = auto()
3869        BINARY = auto()
3870        BIT = auto()
3871        BOOLEAN = auto()
3872        BPCHAR = auto()
3873        CHAR = auto()
3874        DATE = auto()
3875        DATE32 = auto()
3876        DATEMULTIRANGE = auto()
3877        DATERANGE = auto()
3878        DATETIME = auto()
3879        DATETIME64 = auto()
3880        DECIMAL = auto()
3881        DOUBLE = auto()
3882        ENUM = auto()
3883        ENUM8 = auto()
3884        ENUM16 = auto()
3885        FIXEDSTRING = auto()
3886        FLOAT = auto()
3887        GEOGRAPHY = auto()
3888        GEOMETRY = auto()
3889        HLLSKETCH = auto()
3890        HSTORE = auto()
3891        IMAGE = auto()
3892        INET = auto()
3893        INT = auto()
3894        INT128 = auto()
3895        INT256 = auto()
3896        INT4MULTIRANGE = auto()
3897        INT4RANGE = auto()
3898        INT8MULTIRANGE = auto()
3899        INT8RANGE = auto()
3900        INTERVAL = auto()
3901        IPADDRESS = auto()
3902        IPPREFIX = auto()
3903        IPV4 = auto()
3904        IPV6 = auto()
3905        JSON = auto()
3906        JSONB = auto()
3907        LONGBLOB = auto()
3908        LONGTEXT = auto()
3909        LOWCARDINALITY = auto()
3910        MAP = auto()
3911        MEDIUMBLOB = auto()
3912        MEDIUMINT = auto()
3913        MEDIUMTEXT = auto()
3914        MONEY = auto()
3915        NAME = auto()
3916        NCHAR = auto()
3917        NESTED = auto()
3918        NULL = auto()
3919        NULLABLE = auto()
3920        NUMMULTIRANGE = auto()
3921        NUMRANGE = auto()
3922        NVARCHAR = auto()
3923        OBJECT = auto()
3924        ROWVERSION = auto()
3925        SERIAL = auto()
3926        SET = auto()
3927        SMALLINT = auto()
3928        SMALLMONEY = auto()
3929        SMALLSERIAL = auto()
3930        STRUCT = auto()
3931        SUPER = auto()
3932        TEXT = auto()
3933        TINYBLOB = auto()
3934        TINYTEXT = auto()
3935        TIME = auto()
3936        TIMETZ = auto()
3937        TIMESTAMP = auto()
3938        TIMESTAMPLTZ = auto()
3939        TIMESTAMPTZ = auto()
3940        TIMESTAMP_S = auto()
3941        TIMESTAMP_MS = auto()
3942        TIMESTAMP_NS = auto()
3943        TINYINT = auto()
3944        TSMULTIRANGE = auto()
3945        TSRANGE = auto()
3946        TSTZMULTIRANGE = auto()
3947        TSTZRANGE = auto()
3948        UBIGINT = auto()
3949        UINT = auto()
3950        UINT128 = auto()
3951        UINT256 = auto()
3952        UMEDIUMINT = auto()
3953        UDECIMAL = auto()
3954        UNIQUEIDENTIFIER = auto()
3955        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3956        USERDEFINED = "USER-DEFINED"
3957        USMALLINT = auto()
3958        UTINYINT = auto()
3959        UUID = auto()
3960        VARBINARY = auto()
3961        VARCHAR = auto()
3962        VARIANT = auto()
3963        XML = auto()
3964        YEAR = auto()
3965
3966    STRUCT_TYPES = {
3967        Type.NESTED,
3968        Type.OBJECT,
3969        Type.STRUCT,
3970    }
3971
3972    NESTED_TYPES = {
3973        *STRUCT_TYPES,
3974        Type.ARRAY,
3975        Type.MAP,
3976    }
3977
3978    TEXT_TYPES = {
3979        Type.CHAR,
3980        Type.NCHAR,
3981        Type.NVARCHAR,
3982        Type.TEXT,
3983        Type.VARCHAR,
3984        Type.NAME,
3985    }
3986
3987    SIGNED_INTEGER_TYPES = {
3988        Type.BIGINT,
3989        Type.INT,
3990        Type.INT128,
3991        Type.INT256,
3992        Type.MEDIUMINT,
3993        Type.SMALLINT,
3994        Type.TINYINT,
3995    }
3996
3997    UNSIGNED_INTEGER_TYPES = {
3998        Type.UBIGINT,
3999        Type.UINT,
4000        Type.UINT128,
4001        Type.UINT256,
4002        Type.UMEDIUMINT,
4003        Type.USMALLINT,
4004        Type.UTINYINT,
4005    }
4006
4007    INTEGER_TYPES = {
4008        *SIGNED_INTEGER_TYPES,
4009        *UNSIGNED_INTEGER_TYPES,
4010        Type.BIT,
4011    }
4012
4013    FLOAT_TYPES = {
4014        Type.DOUBLE,
4015        Type.FLOAT,
4016    }
4017
4018    REAL_TYPES = {
4019        *FLOAT_TYPES,
4020        Type.BIGDECIMAL,
4021        Type.DECIMAL,
4022        Type.MONEY,
4023        Type.SMALLMONEY,
4024        Type.UDECIMAL,
4025    }
4026
4027    NUMERIC_TYPES = {
4028        *INTEGER_TYPES,
4029        *REAL_TYPES,
4030    }
4031
4032    TEMPORAL_TYPES = {
4033        Type.DATE,
4034        Type.DATE32,
4035        Type.DATETIME,
4036        Type.DATETIME64,
4037        Type.TIME,
4038        Type.TIMESTAMP,
4039        Type.TIMESTAMPLTZ,
4040        Type.TIMESTAMPTZ,
4041        Type.TIMESTAMP_MS,
4042        Type.TIMESTAMP_NS,
4043        Type.TIMESTAMP_S,
4044        Type.TIMETZ,
4045    }
4046
4047    @classmethod
4048    def build(
4049        cls,
4050        dtype: DATA_TYPE,
4051        dialect: DialectType = None,
4052        udt: bool = False,
4053        copy: bool = True,
4054        **kwargs,
4055    ) -> DataType:
4056        """
4057        Constructs a DataType object.
4058
4059        Args:
4060            dtype: the data type of interest.
4061            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4062            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4063                DataType, thus creating a user-defined type.
4064            copy: whether to copy the data type.
4065            kwargs: additional arguments to pass in the constructor of DataType.
4066
4067        Returns:
4068            The constructed DataType object.
4069        """
4070        from sqlglot import parse_one
4071
4072        if isinstance(dtype, str):
4073            if dtype.upper() == "UNKNOWN":
4074                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4075
4076            try:
4077                data_type_exp = parse_one(
4078                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4079                )
4080            except ParseError:
4081                if udt:
4082                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4083                raise
4084        elif isinstance(dtype, DataType.Type):
4085            data_type_exp = DataType(this=dtype)
4086        elif isinstance(dtype, DataType):
4087            return maybe_copy(dtype, copy)
4088        else:
4089            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4090
4091        return DataType(**{**data_type_exp.args, **kwargs})
4092
4093    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4094        """
4095        Checks whether this DataType matches one of the provided data types. Nested types or precision
4096        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4097
4098        Args:
4099            dtypes: the data types to compare this DataType to.
4100
4101        Returns:
4102            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4103        """
4104        for dtype in dtypes:
4105            other = DataType.build(dtype, copy=False, udt=True)
4106
4107            if (
4108                other.expressions
4109                or self.this == DataType.Type.USERDEFINED
4110                or other.this == DataType.Type.USERDEFINED
4111            ):
4112                matches = self == other
4113            else:
4114                matches = self.this == other.this
4115
4116            if matches:
4117                return True
4118        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>}
NESTED_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.ARRAY: 'ARRAY'>, <Type.MAP: 'MAP'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.UINT: 'UINT'>}
INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT256: 'INT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.BIT: 'BIT'>, <Type.UINT256: 'UINT256'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.UINT: 'UINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.MONEY: 'MONEY'>}
NUMERIC_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UTINYINT: 'UTINYINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.BIT: 'BIT'>, <Type.MONEY: 'MONEY'>, <Type.INT128: 'INT128'>, <Type.UINT: 'UINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.INT256: 'INT256'>, <Type.FLOAT: 'FLOAT'>, <Type.UINT256: 'UINT256'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT128: 'UINT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
TEMPORAL_TYPES = {<Type.DATE: 'DATE'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIME: 'TIME'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP: 'TIMESTAMP'>}
@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:
4047    @classmethod
4048    def build(
4049        cls,
4050        dtype: DATA_TYPE,
4051        dialect: DialectType = None,
4052        udt: bool = False,
4053        copy: bool = True,
4054        **kwargs,
4055    ) -> DataType:
4056        """
4057        Constructs a DataType object.
4058
4059        Args:
4060            dtype: the data type of interest.
4061            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4062            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4063                DataType, thus creating a user-defined type.
4064            copy: whether to copy the data type.
4065            kwargs: additional arguments to pass in the constructor of DataType.
4066
4067        Returns:
4068            The constructed DataType object.
4069        """
4070        from sqlglot import parse_one
4071
4072        if isinstance(dtype, str):
4073            if dtype.upper() == "UNKNOWN":
4074                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4075
4076            try:
4077                data_type_exp = parse_one(
4078                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4079                )
4080            except ParseError:
4081                if udt:
4082                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4083                raise
4084        elif isinstance(dtype, DataType.Type):
4085            data_type_exp = DataType(this=dtype)
4086        elif isinstance(dtype, DataType):
4087            return maybe_copy(dtype, copy)
4088        else:
4089            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4090
4091        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:
4093    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4094        """
4095        Checks whether this DataType matches one of the provided data types. Nested types or precision
4096        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4097
4098        Args:
4099            dtypes: the data types to compare this DataType to.
4100
4101        Returns:
4102            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4103        """
4104        for dtype in dtypes:
4105            other = DataType.build(dtype, copy=False, udt=True)
4106
4107            if (
4108                other.expressions
4109                or self.this == DataType.Type.USERDEFINED
4110                or other.this == DataType.Type.USERDEFINED
4111            ):
4112                matches = self == other
4113            else:
4114                matches = self.this == other.this
4115
4116            if matches:
4117                return True
4118        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):
3862    class Type(AutoName):
3863        ARRAY = auto()
3864        AGGREGATEFUNCTION = auto()
3865        SIMPLEAGGREGATEFUNCTION = auto()
3866        BIGDECIMAL = auto()
3867        BIGINT = auto()
3868        BIGSERIAL = auto()
3869        BINARY = auto()
3870        BIT = auto()
3871        BOOLEAN = auto()
3872        BPCHAR = auto()
3873        CHAR = auto()
3874        DATE = auto()
3875        DATE32 = auto()
3876        DATEMULTIRANGE = auto()
3877        DATERANGE = auto()
3878        DATETIME = auto()
3879        DATETIME64 = auto()
3880        DECIMAL = auto()
3881        DOUBLE = auto()
3882        ENUM = auto()
3883        ENUM8 = auto()
3884        ENUM16 = auto()
3885        FIXEDSTRING = auto()
3886        FLOAT = auto()
3887        GEOGRAPHY = auto()
3888        GEOMETRY = auto()
3889        HLLSKETCH = auto()
3890        HSTORE = auto()
3891        IMAGE = auto()
3892        INET = auto()
3893        INT = auto()
3894        INT128 = auto()
3895        INT256 = auto()
3896        INT4MULTIRANGE = auto()
3897        INT4RANGE = auto()
3898        INT8MULTIRANGE = auto()
3899        INT8RANGE = auto()
3900        INTERVAL = auto()
3901        IPADDRESS = auto()
3902        IPPREFIX = auto()
3903        IPV4 = auto()
3904        IPV6 = auto()
3905        JSON = auto()
3906        JSONB = auto()
3907        LONGBLOB = auto()
3908        LONGTEXT = auto()
3909        LOWCARDINALITY = auto()
3910        MAP = auto()
3911        MEDIUMBLOB = auto()
3912        MEDIUMINT = auto()
3913        MEDIUMTEXT = auto()
3914        MONEY = auto()
3915        NAME = auto()
3916        NCHAR = auto()
3917        NESTED = auto()
3918        NULL = auto()
3919        NULLABLE = auto()
3920        NUMMULTIRANGE = auto()
3921        NUMRANGE = auto()
3922        NVARCHAR = auto()
3923        OBJECT = auto()
3924        ROWVERSION = auto()
3925        SERIAL = auto()
3926        SET = auto()
3927        SMALLINT = auto()
3928        SMALLMONEY = auto()
3929        SMALLSERIAL = auto()
3930        STRUCT = auto()
3931        SUPER = auto()
3932        TEXT = auto()
3933        TINYBLOB = auto()
3934        TINYTEXT = auto()
3935        TIME = auto()
3936        TIMETZ = auto()
3937        TIMESTAMP = auto()
3938        TIMESTAMPLTZ = auto()
3939        TIMESTAMPTZ = auto()
3940        TIMESTAMP_S = auto()
3941        TIMESTAMP_MS = auto()
3942        TIMESTAMP_NS = auto()
3943        TINYINT = auto()
3944        TSMULTIRANGE = auto()
3945        TSRANGE = auto()
3946        TSTZMULTIRANGE = auto()
3947        TSTZRANGE = auto()
3948        UBIGINT = auto()
3949        UINT = auto()
3950        UINT128 = auto()
3951        UINT256 = auto()
3952        UMEDIUMINT = auto()
3953        UDECIMAL = auto()
3954        UNIQUEIDENTIFIER = auto()
3955        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3956        USERDEFINED = "USER-DEFINED"
3957        USMALLINT = auto()
3958        UTINYINT = auto()
3959        UUID = auto()
3960        VARBINARY = auto()
3961        VARCHAR = auto()
3962        VARIANT = auto()
3963        XML = auto()
3964        YEAR = 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'>
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'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4125class PseudoType(DataType):
4126    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4130class ObjectIdentifier(DataType):
4131    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4135class SubqueryPredicate(Predicate):
4136    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4139class All(SubqueryPredicate):
4140    pass
key = 'all'
class Any(SubqueryPredicate):
4143class Any(SubqueryPredicate):
4144    pass
key = 'any'
class Exists(SubqueryPredicate):
4147class Exists(SubqueryPredicate):
4148    pass
key = 'exists'
class Command(Expression):
4153class Command(Expression):
4154    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4157class Transaction(Expression):
4158    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4161class Commit(Expression):
4162    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4165class Rollback(Expression):
4166    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4169class AlterTable(Expression):
4170    arg_types = {
4171        "this": True,
4172        "actions": True,
4173        "exists": False,
4174        "only": False,
4175        "options": False,
4176    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
4179class AddConstraint(Expression):
4180    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4183class DropPartition(Expression):
4184    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
4188class Binary(Condition):
4189    arg_types = {"this": True, "expression": True}
4190
4191    @property
4192    def left(self) -> Expression:
4193        return self.this
4194
4195    @property
4196    def right(self) -> Expression:
4197        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4191    @property
4192    def left(self) -> Expression:
4193        return self.this
right: Expression
4195    @property
4196    def right(self) -> Expression:
4197        return self.expression
key = 'binary'
class Add(Binary):
4200class Add(Binary):
4201    pass
key = 'add'
class Connector(Binary):
4204class Connector(Binary):
4205    pass
key = 'connector'
class And(Connector):
4208class And(Connector):
4209    pass
key = 'and'
class Or(Connector):
4212class Or(Connector):
4213    pass
key = 'or'
class BitwiseAnd(Binary):
4216class BitwiseAnd(Binary):
4217    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4220class BitwiseLeftShift(Binary):
4221    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4224class BitwiseOr(Binary):
4225    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4228class BitwiseRightShift(Binary):
4229    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4232class BitwiseXor(Binary):
4233    pass
key = 'bitwisexor'
class Div(Binary):
4236class Div(Binary):
4237    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):
4240class Overlaps(Binary):
4241    pass
key = 'overlaps'
class Dot(Binary):
4244class Dot(Binary):
4245    @property
4246    def is_star(self) -> bool:
4247        return self.expression.is_star
4248
4249    @property
4250    def name(self) -> str:
4251        return self.expression.name
4252
4253    @property
4254    def output_name(self) -> str:
4255        return self.name
4256
4257    @classmethod
4258    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4259        """Build a Dot object with a sequence of expressions."""
4260        if len(expressions) < 2:
4261            raise ValueError("Dot requires >= 2 expressions.")
4262
4263        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4264
4265    @property
4266    def parts(self) -> t.List[Expression]:
4267        """Return the parts of a table / column in order catalog, db, table."""
4268        this, *parts = self.flatten()
4269
4270        parts.reverse()
4271
4272        for arg in COLUMN_PARTS:
4273            part = this.args.get(arg)
4274
4275            if isinstance(part, Expression):
4276                parts.append(part)
4277
4278        parts.reverse()
4279        return parts
is_star: bool
4245    @property
4246    def is_star(self) -> bool:
4247        return self.expression.is_star

Checks whether an expression is a star.

name: str
4249    @property
4250    def name(self) -> str:
4251        return self.expression.name
output_name: str
4253    @property
4254    def output_name(self) -> str:
4255        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:
4257    @classmethod
4258    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4259        """Build a Dot object with a sequence of expressions."""
4260        if len(expressions) < 2:
4261            raise ValueError("Dot requires >= 2 expressions.")
4262
4263        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]
4265    @property
4266    def parts(self) -> t.List[Expression]:
4267        """Return the parts of a table / column in order catalog, db, table."""
4268        this, *parts = self.flatten()
4269
4270        parts.reverse()
4271
4272        for arg in COLUMN_PARTS:
4273            part = this.args.get(arg)
4274
4275            if isinstance(part, Expression):
4276                parts.append(part)
4277
4278        parts.reverse()
4279        return parts

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

key = 'dot'
class DPipe(Binary):
4282class DPipe(Binary):
4283    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4286class EQ(Binary, Predicate):
4287    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4290class NullSafeEQ(Binary, Predicate):
4291    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4294class NullSafeNEQ(Binary, Predicate):
4295    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4299class PropertyEQ(Binary):
4300    pass
key = 'propertyeq'
class Distance(Binary):
4303class Distance(Binary):
4304    pass
key = 'distance'
class Escape(Binary):
4307class Escape(Binary):
4308    pass
key = 'escape'
class Glob(Binary, Predicate):
4311class Glob(Binary, Predicate):
4312    pass
key = 'glob'
class GT(Binary, Predicate):
4315class GT(Binary, Predicate):
4316    pass
key = 'gt'
class GTE(Binary, Predicate):
4319class GTE(Binary, Predicate):
4320    pass
key = 'gte'
class ILike(Binary, Predicate):
4323class ILike(Binary, Predicate):
4324    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4327class ILikeAny(Binary, Predicate):
4328    pass
key = 'ilikeany'
class IntDiv(Binary):
4331class IntDiv(Binary):
4332    pass
key = 'intdiv'
class Is(Binary, Predicate):
4335class Is(Binary, Predicate):
4336    pass
key = 'is'
class Kwarg(Binary):
4339class Kwarg(Binary):
4340    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4343class Like(Binary, Predicate):
4344    pass
key = 'like'
class LikeAny(Binary, Predicate):
4347class LikeAny(Binary, Predicate):
4348    pass
key = 'likeany'
class LT(Binary, Predicate):
4351class LT(Binary, Predicate):
4352    pass
key = 'lt'
class LTE(Binary, Predicate):
4355class LTE(Binary, Predicate):
4356    pass
key = 'lte'
class Mod(Binary):
4359class Mod(Binary):
4360    pass
key = 'mod'
class Mul(Binary):
4363class Mul(Binary):
4364    pass
key = 'mul'
class NEQ(Binary, Predicate):
4367class NEQ(Binary, Predicate):
4368    pass
key = 'neq'
class Operator(Binary):
4372class Operator(Binary):
4373    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4376class SimilarTo(Binary, Predicate):
4377    pass
key = 'similarto'
class Slice(Binary):
4380class Slice(Binary):
4381    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4384class Sub(Binary):
4385    pass
key = 'sub'
class Unary(Condition):
4390class Unary(Condition):
4391    pass
key = 'unary'
class BitwiseNot(Unary):
4394class BitwiseNot(Unary):
4395    pass
key = 'bitwisenot'
class Not(Unary):
4398class Not(Unary):
4399    pass
key = 'not'
class Paren(Unary):
4402class Paren(Unary):
4403    @property
4404    def output_name(self) -> str:
4405        return self.this.name
output_name: str
4403    @property
4404    def output_name(self) -> str:
4405        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):
4408class Neg(Unary):
4409    pass
key = 'neg'
class Alias(Expression):
4412class Alias(Expression):
4413    arg_types = {"this": True, "alias": False}
4414
4415    @property
4416    def output_name(self) -> str:
4417        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4415    @property
4416    def output_name(self) -> str:
4417        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):
4422class PivotAlias(Alias):
4423    pass
key = 'pivotalias'
class Aliases(Expression):
4426class Aliases(Expression):
4427    arg_types = {"this": True, "expressions": True}
4428
4429    @property
4430    def aliases(self):
4431        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4429    @property
4430    def aliases(self):
4431        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4435class AtIndex(Expression):
4436    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4439class AtTimeZone(Expression):
4440    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4443class FromTimeZone(Expression):
4444    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4447class Between(Predicate):
4448    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4451class Bracket(Condition):
4452    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4453    arg_types = {
4454        "this": True,
4455        "expressions": True,
4456        "offset": False,
4457        "safe": False,
4458        "returns_list_for_maps": False,
4459    }
4460
4461    @property
4462    def output_name(self) -> str:
4463        if len(self.expressions) == 1:
4464            return self.expressions[0].output_name
4465
4466        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4461    @property
4462    def output_name(self) -> str:
4463        if len(self.expressions) == 1:
4464            return self.expressions[0].output_name
4465
4466        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):
4469class Distinct(Expression):
4470    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4473class In(Predicate):
4474    arg_types = {
4475        "this": True,
4476        "expressions": False,
4477        "query": False,
4478        "unnest": False,
4479        "field": False,
4480        "is_global": False,
4481    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4485class ForIn(Expression):
4486    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4489class TimeUnit(Expression):
4490    """Automatically converts unit arg into a var."""
4491
4492    arg_types = {"unit": False}
4493
4494    UNABBREVIATED_UNIT_NAME = {
4495        "D": "DAY",
4496        "H": "HOUR",
4497        "M": "MINUTE",
4498        "MS": "MILLISECOND",
4499        "NS": "NANOSECOND",
4500        "Q": "QUARTER",
4501        "S": "SECOND",
4502        "US": "MICROSECOND",
4503        "W": "WEEK",
4504        "Y": "YEAR",
4505    }
4506
4507    VAR_LIKE = (Column, Literal, Var)
4508
4509    def __init__(self, **args):
4510        unit = args.get("unit")
4511        if isinstance(unit, self.VAR_LIKE):
4512            args["unit"] = Var(
4513                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4514            )
4515        elif isinstance(unit, Week):
4516            unit.set("this", Var(this=unit.this.name.upper()))
4517
4518        super().__init__(**args)
4519
4520    @property
4521    def unit(self) -> t.Optional[Var | IntervalSpan]:
4522        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4509    def __init__(self, **args):
4510        unit = args.get("unit")
4511        if isinstance(unit, self.VAR_LIKE):
4512            args["unit"] = Var(
4513                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4514            )
4515        elif isinstance(unit, Week):
4516            unit.set("this", Var(this=unit.this.name.upper()))
4517
4518        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]
4520    @property
4521    def unit(self) -> t.Optional[Var | IntervalSpan]:
4522        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4525class IntervalOp(TimeUnit):
4526    arg_types = {"unit": True, "expression": True}
4527
4528    def interval(self):
4529        return Interval(
4530            this=self.expression.copy(),
4531            unit=self.unit.copy(),
4532        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4528    def interval(self):
4529        return Interval(
4530            this=self.expression.copy(),
4531            unit=self.unit.copy(),
4532        )
key = 'intervalop'
class IntervalSpan(DataType):
4538class IntervalSpan(DataType):
4539    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4542class Interval(TimeUnit):
4543    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4546class IgnoreNulls(Expression):
4547    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4550class RespectNulls(Expression):
4551    pass
key = 'respectnulls'
class HavingMax(Expression):
4555class HavingMax(Expression):
4556    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4560class Func(Condition):
4561    """
4562    The base class for all function expressions.
4563
4564    Attributes:
4565        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4566            treated as a variable length argument and the argument's value will be stored as a list.
4567        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4568            function expression. These values are used to map this node to a name during parsing as
4569            well as to provide the function's name during SQL string generation. By default the SQL
4570            name is set to the expression's class name transformed to snake case.
4571    """
4572
4573    is_var_len_args = False
4574
4575    @classmethod
4576    def from_arg_list(cls, args):
4577        if cls.is_var_len_args:
4578            all_arg_keys = list(cls.arg_types)
4579            # If this function supports variable length argument treat the last argument as such.
4580            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4581            num_non_var = len(non_var_len_arg_keys)
4582
4583            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4584            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4585        else:
4586            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4587
4588        return cls(**args_dict)
4589
4590    @classmethod
4591    def sql_names(cls):
4592        if cls is Func:
4593            raise NotImplementedError(
4594                "SQL name is only supported by concrete function implementations"
4595            )
4596        if "_sql_names" not in cls.__dict__:
4597            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4598        return cls._sql_names
4599
4600    @classmethod
4601    def sql_name(cls):
4602        return cls.sql_names()[0]
4603
4604    @classmethod
4605    def default_parser_mappings(cls):
4606        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):
4575    @classmethod
4576    def from_arg_list(cls, args):
4577        if cls.is_var_len_args:
4578            all_arg_keys = list(cls.arg_types)
4579            # If this function supports variable length argument treat the last argument as such.
4580            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4581            num_non_var = len(non_var_len_arg_keys)
4582
4583            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4584            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4585        else:
4586            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4587
4588        return cls(**args_dict)
@classmethod
def sql_names(cls):
4590    @classmethod
4591    def sql_names(cls):
4592        if cls is Func:
4593            raise NotImplementedError(
4594                "SQL name is only supported by concrete function implementations"
4595            )
4596        if "_sql_names" not in cls.__dict__:
4597            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4598        return cls._sql_names
@classmethod
def sql_name(cls):
4600    @classmethod
4601    def sql_name(cls):
4602        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4604    @classmethod
4605    def default_parser_mappings(cls):
4606        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4609class AggFunc(Func):
4610    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4613class ParameterizedAgg(AggFunc):
4614    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4617class Abs(Func):
4618    pass
key = 'abs'
class ArgMax(AggFunc):
4621class ArgMax(AggFunc):
4622    arg_types = {"this": True, "expression": True, "count": False}
4623    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4626class ArgMin(AggFunc):
4627    arg_types = {"this": True, "expression": True, "count": False}
4628    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4631class ApproxTopK(AggFunc):
4632    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4635class Flatten(Func):
4636    pass
key = 'flatten'
class Transform(Func):
4640class Transform(Func):
4641    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4644class Anonymous(Func):
4645    arg_types = {"this": True, "expressions": False}
4646    is_var_len_args = True
4647
4648    @property
4649    def name(self) -> str:
4650        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
4648    @property
4649    def name(self) -> str:
4650        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4653class AnonymousAggFunc(AggFunc):
4654    arg_types = {"this": True, "expressions": False}
4655    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4659class CombinedAggFunc(AnonymousAggFunc):
4660    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4663class CombinedParameterizedAgg(ParameterizedAgg):
4664    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):
4669class Hll(AggFunc):
4670    arg_types = {"this": True, "expressions": False}
4671    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4674class ApproxDistinct(AggFunc):
4675    arg_types = {"this": True, "accuracy": False}
4676    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4679class Array(Func):
4680    arg_types = {"expressions": False}
4681    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4685class ToArray(Func):
4686    pass
key = 'toarray'
class ToChar(Func):
4691class ToChar(Func):
4692    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4697class ToNumber(Func):
4698    arg_types = {
4699        "this": True,
4700        "format": False,
4701        "nlsparam": False,
4702        "precision": False,
4703        "scale": False,
4704    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4708class Convert(Func):
4709    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4712class GenerateSeries(Func):
4713    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):
4716class ArrayAgg(AggFunc):
4717    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4720class ArrayUniqueAgg(AggFunc):
4721    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4724class ArrayAll(Func):
4725    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4729class ArrayAny(Func):
4730    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4733class ArrayConcat(Func):
4734    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4735    arg_types = {"this": True, "expressions": False}
4736    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4739class ArrayContains(Binary, Func):
4740    pass
key = 'arraycontains'
class ArrayContained(Binary):
4743class ArrayContained(Binary):
4744    pass
key = 'arraycontained'
class ArrayFilter(Func):
4747class ArrayFilter(Func):
4748    arg_types = {"this": True, "expression": True}
4749    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4752class ArrayToString(Func):
4753    arg_types = {"this": True, "expression": True, "null": False}
4754    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4757class ArrayOverlaps(Binary, Func):
4758    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4761class ArraySize(Func):
4762    arg_types = {"this": True, "expression": False}
4763    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4766class ArraySort(Func):
4767    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4770class ArraySum(Func):
4771    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4774class ArrayUnionAgg(AggFunc):
4775    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4778class Avg(AggFunc):
4779    pass
key = 'avg'
class AnyValue(AggFunc):
4782class AnyValue(AggFunc):
4783    pass
key = 'anyvalue'
class Lag(AggFunc):
4786class Lag(AggFunc):
4787    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4790class Lead(AggFunc):
4791    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4796class First(AggFunc):
4797    pass
key = 'first'
class Last(AggFunc):
4800class Last(AggFunc):
4801    pass
key = 'last'
class FirstValue(AggFunc):
4804class FirstValue(AggFunc):
4805    pass
key = 'firstvalue'
class LastValue(AggFunc):
4808class LastValue(AggFunc):
4809    pass
key = 'lastvalue'
class NthValue(AggFunc):
4812class NthValue(AggFunc):
4813    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4816class Case(Func):
4817    arg_types = {"this": False, "ifs": True, "default": False}
4818
4819    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4820        instance = maybe_copy(self, copy)
4821        instance.append(
4822            "ifs",
4823            If(
4824                this=maybe_parse(condition, copy=copy, **opts),
4825                true=maybe_parse(then, copy=copy, **opts),
4826            ),
4827        )
4828        return instance
4829
4830    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4831        instance = maybe_copy(self, copy)
4832        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4833        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:
4819    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4820        instance = maybe_copy(self, copy)
4821        instance.append(
4822            "ifs",
4823            If(
4824                this=maybe_parse(condition, copy=copy, **opts),
4825                true=maybe_parse(then, copy=copy, **opts),
4826            ),
4827        )
4828        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4830    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4831        instance = maybe_copy(self, copy)
4832        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4833        return instance
key = 'case'
class Cast(Func):
4836class Cast(Func):
4837    arg_types = {
4838        "this": True,
4839        "to": True,
4840        "format": False,
4841        "safe": False,
4842        "action": False,
4843    }
4844
4845    @property
4846    def name(self) -> str:
4847        return self.this.name
4848
4849    @property
4850    def to(self) -> DataType:
4851        return self.args["to"]
4852
4853    @property
4854    def output_name(self) -> str:
4855        return self.name
4856
4857    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4858        """
4859        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4860        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4861        array<int> != array<float>.
4862
4863        Args:
4864            dtypes: the data types to compare this Cast's DataType to.
4865
4866        Returns:
4867            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4868        """
4869        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4845    @property
4846    def name(self) -> str:
4847        return self.this.name
to: DataType
4849    @property
4850    def to(self) -> DataType:
4851        return self.args["to"]
output_name: str
4853    @property
4854    def output_name(self) -> str:
4855        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:
4857    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4858        """
4859        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4860        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4861        array<int> != array<float>.
4862
4863        Args:
4864            dtypes: the data types to compare this Cast's DataType to.
4865
4866        Returns:
4867            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4868        """
4869        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):
4872class TryCast(Cast):
4873    pass
key = 'trycast'
class CastToStrType(Func):
4876class CastToStrType(Func):
4877    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4880class Collate(Binary, Func):
4881    pass
key = 'collate'
class Ceil(Func):
4884class Ceil(Func):
4885    arg_types = {"this": True, "decimals": False}
4886    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4889class Coalesce(Func):
4890    arg_types = {"this": True, "expressions": False}
4891    is_var_len_args = True
4892    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4895class Chr(Func):
4896    arg_types = {"this": True, "charset": False, "expressions": False}
4897    is_var_len_args = True
4898    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4901class Concat(Func):
4902    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4903    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4906class ConcatWs(Concat):
4907    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4911class ConnectByRoot(Func):
4912    pass
key = 'connectbyroot'
class Count(AggFunc):
4915class Count(AggFunc):
4916    arg_types = {"this": False, "expressions": False}
4917    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4920class CountIf(AggFunc):
4921    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4925class Cbrt(Func):
4926    pass
key = 'cbrt'
class CurrentDate(Func):
4929class CurrentDate(Func):
4930    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4933class CurrentDatetime(Func):
4934    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4937class CurrentTime(Func):
4938    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4941class CurrentTimestamp(Func):
4942    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4945class CurrentUser(Func):
4946    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4949class DateAdd(Func, IntervalOp):
4950    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4953class DateSub(Func, IntervalOp):
4954    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4957class DateDiff(Func, TimeUnit):
4958    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4959    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4962class DateTrunc(Func):
4963    arg_types = {"unit": True, "this": True, "zone": False}
4964
4965    def __init__(self, **args):
4966        unit = args.get("unit")
4967        if isinstance(unit, TimeUnit.VAR_LIKE):
4968            args["unit"] = Literal.string(
4969                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4970            )
4971        elif isinstance(unit, Week):
4972            unit.set("this", Literal.string(unit.this.name.upper()))
4973
4974        super().__init__(**args)
4975
4976    @property
4977    def unit(self) -> Expression:
4978        return self.args["unit"]
DateTrunc(**args)
4965    def __init__(self, **args):
4966        unit = args.get("unit")
4967        if isinstance(unit, TimeUnit.VAR_LIKE):
4968            args["unit"] = Literal.string(
4969                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4970            )
4971        elif isinstance(unit, Week):
4972            unit.set("this", Literal.string(unit.this.name.upper()))
4973
4974        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4976    @property
4977    def unit(self) -> Expression:
4978        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4981class DatetimeAdd(Func, IntervalOp):
4982    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4985class DatetimeSub(Func, IntervalOp):
4986    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4989class DatetimeDiff(Func, TimeUnit):
4990    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4993class DatetimeTrunc(Func, TimeUnit):
4994    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4997class DayOfWeek(Func):
4998    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5001class DayOfMonth(Func):
5002    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5005class DayOfYear(Func):
5006    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5009class ToDays(Func):
5010    pass
key = 'todays'
class WeekOfYear(Func):
5013class WeekOfYear(Func):
5014    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5017class MonthsBetween(Func):
5018    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5021class LastDay(Func, TimeUnit):
5022    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5023    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5026class Extract(Func):
5027    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5030class Timestamp(Func):
5031    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5034class TimestampAdd(Func, TimeUnit):
5035    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5038class TimestampSub(Func, TimeUnit):
5039    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5042class TimestampDiff(Func, TimeUnit):
5043    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5044    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5047class TimestampTrunc(Func, TimeUnit):
5048    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5051class TimeAdd(Func, TimeUnit):
5052    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5055class TimeSub(Func, TimeUnit):
5056    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5059class TimeDiff(Func, TimeUnit):
5060    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5063class TimeTrunc(Func, TimeUnit):
5064    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5067class DateFromParts(Func):
5068    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5069    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5072class TimeFromParts(Func):
5073    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5074    arg_types = {
5075        "hour": True,
5076        "min": True,
5077        "sec": True,
5078        "nano": False,
5079        "fractions": False,
5080        "precision": False,
5081    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5084class DateStrToDate(Func):
5085    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5088class DateToDateStr(Func):
5089    pass
key = 'datetodatestr'
class DateToDi(Func):
5092class DateToDi(Func):
5093    pass
key = 'datetodi'
class Date(Func):
5097class Date(Func):
5098    arg_types = {"this": False, "zone": False, "expressions": False}
5099    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5102class Day(Func):
5103    pass
key = 'day'
class Decode(Func):
5106class Decode(Func):
5107    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5110class DiToDate(Func):
5111    pass
key = 'ditodate'
class Encode(Func):
5114class Encode(Func):
5115    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5118class Exp(Func):
5119    pass
key = 'exp'
class Explode(Func):
5123class Explode(Func):
5124    arg_types = {"this": True, "expressions": False}
5125    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5128class ExplodeOuter(Explode):
5129    pass
key = 'explodeouter'
class Posexplode(Explode):
5132class Posexplode(Explode):
5133    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5136class PosexplodeOuter(Posexplode, ExplodeOuter):
5137    pass
key = 'posexplodeouter'
class Floor(Func):
5140class Floor(Func):
5141    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5144class FromBase64(Func):
5145    pass
key = 'frombase64'
class ToBase64(Func):
5148class ToBase64(Func):
5149    pass
key = 'tobase64'
class GenerateDateArray(Func):
5152class GenerateDateArray(Func):
5153    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5156class Greatest(Func):
5157    arg_types = {"this": True, "expressions": False}
5158    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5161class GroupConcat(AggFunc):
5162    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5165class Hex(Func):
5166    pass
key = 'hex'
class Xor(Connector, Func):
5169class Xor(Connector, Func):
5170    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5173class If(Func):
5174    arg_types = {"this": True, "true": True, "false": False}
5175    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5178class Nullif(Func):
5179    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5182class Initcap(Func):
5183    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5186class IsNan(Func):
5187    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5190class IsInf(Func):
5191    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5194class JSONPath(Expression):
5195    arg_types = {"expressions": True}
5196
5197    @property
5198    def output_name(self) -> str:
5199        last_segment = self.expressions[-1].this
5200        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5197    @property
5198    def output_name(self) -> str:
5199        last_segment = self.expressions[-1].this
5200        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):
5203class JSONPathPart(Expression):
5204    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5207class JSONPathFilter(JSONPathPart):
5208    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5211class JSONPathKey(JSONPathPart):
5212    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5215class JSONPathRecursive(JSONPathPart):
5216    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5219class JSONPathRoot(JSONPathPart):
5220    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5223class JSONPathScript(JSONPathPart):
5224    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5227class JSONPathSlice(JSONPathPart):
5228    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5231class JSONPathSelector(JSONPathPart):
5232    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5235class JSONPathSubscript(JSONPathPart):
5236    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5239class JSONPathUnion(JSONPathPart):
5240    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5243class JSONPathWildcard(JSONPathPart):
5244    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5247class FormatJson(Expression):
5248    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5251class JSONKeyValue(Expression):
5252    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5255class JSONObject(Func):
5256    arg_types = {
5257        "expressions": False,
5258        "null_handling": False,
5259        "unique_keys": False,
5260        "return_type": False,
5261        "encoding": False,
5262    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5265class JSONObjectAgg(AggFunc):
5266    arg_types = {
5267        "expressions": False,
5268        "null_handling": False,
5269        "unique_keys": False,
5270        "return_type": False,
5271        "encoding": False,
5272    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5276class JSONArray(Func):
5277    arg_types = {
5278        "expressions": True,
5279        "null_handling": False,
5280        "return_type": False,
5281        "strict": False,
5282    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5286class JSONArrayAgg(Func):
5287    arg_types = {
5288        "this": True,
5289        "order": False,
5290        "null_handling": False,
5291        "return_type": False,
5292        "strict": False,
5293    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5298class JSONColumnDef(Expression):
5299    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):
5302class JSONSchema(Expression):
5303    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5307class JSONTable(Func):
5308    arg_types = {
5309        "this": True,
5310        "schema": True,
5311        "path": False,
5312        "error_handling": False,
5313        "empty_handling": False,
5314    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5317class OpenJSONColumnDef(Expression):
5318    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):
5321class OpenJSON(Func):
5322    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5325class JSONBContains(Binary):
5326    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5329class JSONExtract(Binary, Func):
5330    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5331    _sql_names = ["JSON_EXTRACT"]
5332    is_var_len_args = True
5333
5334    @property
5335    def output_name(self) -> str:
5336        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
5334    @property
5335    def output_name(self) -> str:
5336        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):
5339class JSONExtractScalar(Binary, Func):
5340    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5341    _sql_names = ["JSON_EXTRACT_SCALAR"]
5342    is_var_len_args = True
5343
5344    @property
5345    def output_name(self) -> str:
5346        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
5344    @property
5345    def output_name(self) -> str:
5346        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):
5349class JSONBExtract(Binary, Func):
5350    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5353class JSONBExtractScalar(Binary, Func):
5354    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5357class JSONFormat(Func):
5358    arg_types = {"this": False, "options": False}
5359    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5363class JSONArrayContains(Binary, Predicate, Func):
5364    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5367class ParseJSON(Func):
5368    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5369    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5370    arg_types = {"this": True, "expressions": False}
5371    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5374class Least(Func):
5375    arg_types = {"this": True, "expressions": False}
5376    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5379class Left(Func):
5380    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5387class Length(Func):
5388    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5391class Levenshtein(Func):
5392    arg_types = {
5393        "this": True,
5394        "expression": False,
5395        "ins_cost": False,
5396        "del_cost": False,
5397        "sub_cost": False,
5398    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5401class Ln(Func):
5402    pass
key = 'ln'
class Log(Func):
5405class Log(Func):
5406    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5409class LogicalOr(AggFunc):
5410    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5413class LogicalAnd(AggFunc):
5414    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5417class Lower(Func):
5418    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5421class Map(Func):
5422    arg_types = {"keys": False, "values": False}
5423
5424    @property
5425    def keys(self) -> t.List[Expression]:
5426        keys = self.args.get("keys")
5427        return keys.expressions if keys else []
5428
5429    @property
5430    def values(self) -> t.List[Expression]:
5431        values = self.args.get("values")
5432        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5424    @property
5425    def keys(self) -> t.List[Expression]:
5426        keys = self.args.get("keys")
5427        return keys.expressions if keys else []
values: List[Expression]
5429    @property
5430    def values(self) -> t.List[Expression]:
5431        values = self.args.get("values")
5432        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5436class ToMap(Func):
5437    pass
key = 'tomap'
class MapFromEntries(Func):
5440class MapFromEntries(Func):
5441    pass
key = 'mapfromentries'
class StarMap(Func):
5444class StarMap(Func):
5445    pass
key = 'starmap'
class VarMap(Func):
5448class VarMap(Func):
5449    arg_types = {"keys": True, "values": True}
5450    is_var_len_args = True
5451
5452    @property
5453    def keys(self) -> t.List[Expression]:
5454        return self.args["keys"].expressions
5455
5456    @property
5457    def values(self) -> t.List[Expression]:
5458        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5452    @property
5453    def keys(self) -> t.List[Expression]:
5454        return self.args["keys"].expressions
values: List[Expression]
5456    @property
5457    def values(self) -> t.List[Expression]:
5458        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5462class MatchAgainst(Func):
5463    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5466class Max(AggFunc):
5467    arg_types = {"this": True, "expressions": False}
5468    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5471class MD5(Func):
5472    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5476class MD5Digest(Func):
5477    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5480class Min(AggFunc):
5481    arg_types = {"this": True, "expressions": False}
5482    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5485class Month(Func):
5486    pass
key = 'month'
class AddMonths(Func):
5489class AddMonths(Func):
5490    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5493class Nvl2(Func):
5494    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5498class Predict(Func):
5499    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5502class Pow(Binary, Func):
5503    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5506class PercentileCont(AggFunc):
5507    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5510class PercentileDisc(AggFunc):
5511    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5514class Quantile(AggFunc):
5515    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5518class ApproxQuantile(Quantile):
5519    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):
5522class Quarter(Func):
5523    pass
key = 'quarter'
class Rand(Func):
5526class Rand(Func):
5527    _sql_names = ["RAND", "RANDOM"]
5528    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5531class Randn(Func):
5532    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5535class RangeN(Func):
5536    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5539class ReadCSV(Func):
5540    _sql_names = ["READ_CSV"]
5541    is_var_len_args = True
5542    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5545class Reduce(Func):
5546    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):
5549class RegexpExtract(Func):
5550    arg_types = {
5551        "this": True,
5552        "expression": True,
5553        "position": False,
5554        "occurrence": False,
5555        "parameters": False,
5556        "group": False,
5557    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5560class RegexpReplace(Func):
5561    arg_types = {
5562        "this": True,
5563        "expression": True,
5564        "replacement": False,
5565        "position": False,
5566        "occurrence": False,
5567        "parameters": False,
5568        "modifiers": False,
5569    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5572class RegexpLike(Binary, Func):
5573    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5576class RegexpILike(Binary, Func):
5577    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5582class RegexpSplit(Func):
5583    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5586class Repeat(Func):
5587    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5592class Round(Func):
5593    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5596class RowNumber(Func):
5597    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5600class SafeDivide(Func):
5601    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5604class SHA(Func):
5605    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5608class SHA2(Func):
5609    _sql_names = ["SHA2"]
5610    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5613class Sign(Func):
5614    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5617class SortArray(Func):
5618    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5621class Split(Func):
5622    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5627class Substring(Func):
5628    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5631class StandardHash(Func):
5632    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5635class StartsWith(Func):
5636    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5637    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5640class StrPosition(Func):
5641    arg_types = {
5642        "this": True,
5643        "substr": True,
5644        "position": False,
5645        "instance": False,
5646    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5649class StrToDate(Func):
5650    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5653class StrToTime(Func):
5654    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5659class StrToUnix(Func):
5660    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5665class StrToMap(Func):
5666    arg_types = {
5667        "this": True,
5668        "pair_delim": False,
5669        "key_value_delim": False,
5670        "duplicate_resolution_callback": False,
5671    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5674class NumberToStr(Func):
5675    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5678class FromBase(Func):
5679    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5682class Struct(Func):
5683    arg_types = {"expressions": False}
5684    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5687class StructExtract(Func):
5688    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5693class Stuff(Func):
5694    _sql_names = ["STUFF", "INSERT"]
5695    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):
5698class Sum(AggFunc):
5699    pass
key = 'sum'
class Sqrt(Func):
5702class Sqrt(Func):
5703    pass
key = 'sqrt'
class Stddev(AggFunc):
5706class Stddev(AggFunc):
5707    pass
key = 'stddev'
class StddevPop(AggFunc):
5710class StddevPop(AggFunc):
5711    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5714class StddevSamp(AggFunc):
5715    pass
key = 'stddevsamp'
class TimeToStr(Func):
5718class TimeToStr(Func):
5719    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):
5722class TimeToTimeStr(Func):
5723    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5726class TimeToUnix(Func):
5727    pass
key = 'timetounix'
class TimeStrToDate(Func):
5730class TimeStrToDate(Func):
5731    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5734class TimeStrToTime(Func):
5735    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5738class TimeStrToUnix(Func):
5739    pass
key = 'timestrtounix'
class Trim(Func):
5742class Trim(Func):
5743    arg_types = {
5744        "this": True,
5745        "expression": False,
5746        "position": False,
5747        "collation": False,
5748    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5751class TsOrDsAdd(Func, TimeUnit):
5752    # return_type is used to correctly cast the arguments of this expression when transpiling it
5753    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5754
5755    @property
5756    def return_type(self) -> DataType:
5757        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
5755    @property
5756    def return_type(self) -> DataType:
5757        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5760class TsOrDsDiff(Func, TimeUnit):
5761    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5764class TsOrDsToDateStr(Func):
5765    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5768class TsOrDsToDate(Func):
5769    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5772class TsOrDsToTime(Func):
5773    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5776class TsOrDsToTimestamp(Func):
5777    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5780class TsOrDiToDi(Func):
5781    pass
key = 'tsorditodi'
class Unhex(Func):
5784class Unhex(Func):
5785    pass
key = 'unhex'
class UnixDate(Func):
5789class UnixDate(Func):
5790    pass
key = 'unixdate'
class UnixToStr(Func):
5793class UnixToStr(Func):
5794    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5799class UnixToTime(Func):
5800    arg_types = {
5801        "this": True,
5802        "scale": False,
5803        "zone": False,
5804        "hours": False,
5805        "minutes": False,
5806        "format": False,
5807    }
5808
5809    SECONDS = Literal.number(0)
5810    DECIS = Literal.number(1)
5811    CENTIS = Literal.number(2)
5812    MILLIS = Literal.number(3)
5813    DECIMILLIS = Literal.number(4)
5814    CENTIMILLIS = Literal.number(5)
5815    MICROS = Literal.number(6)
5816    DECIMICROS = Literal.number(7)
5817    CENTIMICROS = Literal.number(8)
5818    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):
5821class UnixToTimeStr(Func):
5822    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5825class TimestampFromParts(Func):
5826    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5827    arg_types = {
5828        "year": True,
5829        "month": True,
5830        "day": True,
5831        "hour": True,
5832        "min": True,
5833        "sec": True,
5834        "nano": False,
5835        "zone": False,
5836        "milli": False,
5837    }
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):
5840class Upper(Func):
5841    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5844class Corr(Binary, AggFunc):
5845    pass
key = 'corr'
class Variance(AggFunc):
5848class Variance(AggFunc):
5849    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5852class VariancePop(AggFunc):
5853    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5856class CovarSamp(Binary, AggFunc):
5857    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5860class CovarPop(Binary, AggFunc):
5861    pass
key = 'covarpop'
class Week(Func):
5864class Week(Func):
5865    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5868class XMLTable(Func):
5869    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):
5872class Year(Func):
5873    pass
key = 'year'
class Use(Expression):
5876class Use(Expression):
5877    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5880class Merge(Expression):
5881    arg_types = {
5882        "this": True,
5883        "using": True,
5884        "on": True,
5885        "expressions": True,
5886        "with": False,
5887    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5890class When(Func):
5891    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):
5896class NextValueFor(Func):
5897    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
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 '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 '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 '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_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'>, '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_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:
5937def maybe_parse(
5938    sql_or_expression: ExpOrStr,
5939    *,
5940    into: t.Optional[IntoType] = None,
5941    dialect: DialectType = None,
5942    prefix: t.Optional[str] = None,
5943    copy: bool = False,
5944    **opts,
5945) -> Expression:
5946    """Gracefully handle a possible string or expression.
5947
5948    Example:
5949        >>> maybe_parse("1")
5950        Literal(this=1, is_string=False)
5951        >>> maybe_parse(to_identifier("x"))
5952        Identifier(this=x, quoted=False)
5953
5954    Args:
5955        sql_or_expression: the SQL code string or an expression
5956        into: the SQLGlot Expression to parse into
5957        dialect: the dialect used to parse the input expressions (in the case that an
5958            input expression is a SQL string).
5959        prefix: a string to prefix the sql with before it gets parsed
5960            (automatically includes a space)
5961        copy: whether to copy the expression.
5962        **opts: other options to use to parse the input expressions (again, in the case
5963            that an input expression is a SQL string).
5964
5965    Returns:
5966        Expression: the parsed or given expression.
5967    """
5968    if isinstance(sql_or_expression, Expression):
5969        if copy:
5970            return sql_or_expression.copy()
5971        return sql_or_expression
5972
5973    if sql_or_expression is None:
5974        raise ParseError("SQL cannot be None")
5975
5976    import sqlglot
5977
5978    sql = str(sql_or_expression)
5979    if prefix:
5980        sql = f"{prefix} {sql}"
5981
5982    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):
5993def maybe_copy(instance, copy=True):
5994    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:
6208def union(
6209    left: ExpOrStr,
6210    right: ExpOrStr,
6211    distinct: bool = True,
6212    dialect: DialectType = None,
6213    copy: bool = True,
6214    **opts,
6215) -> Union:
6216    """
6217    Initializes a syntax tree from one UNION expression.
6218
6219    Example:
6220        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6221        'SELECT * FROM foo UNION SELECT * FROM bla'
6222
6223    Args:
6224        left: the SQL code string corresponding to the left-hand side.
6225            If an `Expression` instance is passed, it will be used as-is.
6226        right: the SQL code string corresponding to the right-hand side.
6227            If an `Expression` instance is passed, it will be used as-is.
6228        distinct: set the DISTINCT flag if and only if this is true.
6229        dialect: the dialect used to parse the input expression.
6230        copy: whether to copy the expression.
6231        opts: other options to use to parse the input expressions.
6232
6233    Returns:
6234        The new Union instance.
6235    """
6236    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6237    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6238
6239    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:
6242def intersect(
6243    left: ExpOrStr,
6244    right: ExpOrStr,
6245    distinct: bool = True,
6246    dialect: DialectType = None,
6247    copy: bool = True,
6248    **opts,
6249) -> Intersect:
6250    """
6251    Initializes a syntax tree from one INTERSECT expression.
6252
6253    Example:
6254        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6255        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6256
6257    Args:
6258        left: the SQL code string corresponding to the left-hand side.
6259            If an `Expression` instance is passed, it will be used as-is.
6260        right: the SQL code string corresponding to the right-hand side.
6261            If an `Expression` instance is passed, it will be used as-is.
6262        distinct: set the DISTINCT flag if and only if this is true.
6263        dialect: the dialect used to parse the input expression.
6264        copy: whether to copy the expression.
6265        opts: other options to use to parse the input expressions.
6266
6267    Returns:
6268        The new Intersect instance.
6269    """
6270    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6271    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6272
6273    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:
6276def except_(
6277    left: ExpOrStr,
6278    right: ExpOrStr,
6279    distinct: bool = True,
6280    dialect: DialectType = None,
6281    copy: bool = True,
6282    **opts,
6283) -> Except:
6284    """
6285    Initializes a syntax tree from one EXCEPT expression.
6286
6287    Example:
6288        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6289        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6290
6291    Args:
6292        left: the SQL code string corresponding to the left-hand side.
6293            If an `Expression` instance is passed, it will be used as-is.
6294        right: the SQL code string corresponding to the right-hand side.
6295            If an `Expression` instance is passed, it will be used as-is.
6296        distinct: set the DISTINCT flag if and only if this is true.
6297        dialect: the dialect used to parse the input expression.
6298        copy: whether to copy the expression.
6299        opts: other options to use to parse the input expressions.
6300
6301    Returns:
6302        The new Except instance.
6303    """
6304    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6305    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6306
6307    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:
6310def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6311    """
6312    Initializes a syntax tree from one or multiple SELECT expressions.
6313
6314    Example:
6315        >>> select("col1", "col2").from_("tbl").sql()
6316        'SELECT col1, col2 FROM tbl'
6317
6318    Args:
6319        *expressions: the SQL code string to parse as the expressions of a
6320            SELECT statement. If an Expression instance is passed, this is used as-is.
6321        dialect: the dialect used to parse the input expressions (in the case that an
6322            input expression is a SQL string).
6323        **opts: other options to use to parse the input expressions (again, in the case
6324            that an input expression is a SQL string).
6325
6326    Returns:
6327        Select: the syntax tree for the SELECT statement.
6328    """
6329    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:
6332def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6333    """
6334    Initializes a syntax tree from a FROM expression.
6335
6336    Example:
6337        >>> from_("tbl").select("col1", "col2").sql()
6338        'SELECT col1, col2 FROM tbl'
6339
6340    Args:
6341        *expression: the SQL code string to parse as the FROM expressions of a
6342            SELECT statement. If an Expression instance is passed, this is used as-is.
6343        dialect: the dialect used to parse the input expression (in the case that the
6344            input expression is a SQL string).
6345        **opts: other options to use to parse the input expressions (again, in the case
6346            that the input expression is a SQL string).
6347
6348    Returns:
6349        Select: the syntax tree for the SELECT statement.
6350    """
6351    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:
6354def update(
6355    table: str | Table,
6356    properties: dict,
6357    where: t.Optional[ExpOrStr] = None,
6358    from_: t.Optional[ExpOrStr] = None,
6359    dialect: DialectType = None,
6360    **opts,
6361) -> Update:
6362    """
6363    Creates an update statement.
6364
6365    Example:
6366        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6367        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6368
6369    Args:
6370        *properties: dictionary of properties to set which are
6371            auto converted to sql objects eg None -> NULL
6372        where: sql conditional parsed into a WHERE statement
6373        from_: sql statement parsed into a FROM statement
6374        dialect: the dialect used to parse the input expressions.
6375        **opts: other options to use to parse the input expressions.
6376
6377    Returns:
6378        Update: the syntax tree for the UPDATE statement.
6379    """
6380    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6381    update_expr.set(
6382        "expressions",
6383        [
6384            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6385            for k, v in properties.items()
6386        ],
6387    )
6388    if from_:
6389        update_expr.set(
6390            "from",
6391            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6392        )
6393    if isinstance(where, Condition):
6394        where = Where(this=where)
6395    if where:
6396        update_expr.set(
6397            "where",
6398            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6399        )
6400    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:
6403def delete(
6404    table: ExpOrStr,
6405    where: t.Optional[ExpOrStr] = None,
6406    returning: t.Optional[ExpOrStr] = None,
6407    dialect: DialectType = None,
6408    **opts,
6409) -> Delete:
6410    """
6411    Builds a delete statement.
6412
6413    Example:
6414        >>> delete("my_table", where="id > 1").sql()
6415        'DELETE FROM my_table WHERE id > 1'
6416
6417    Args:
6418        where: sql conditional parsed into a WHERE statement
6419        returning: sql conditional parsed into a RETURNING statement
6420        dialect: the dialect used to parse the input expressions.
6421        **opts: other options to use to parse the input expressions.
6422
6423    Returns:
6424        Delete: the syntax tree for the DELETE statement.
6425    """
6426    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6427    if where:
6428        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6429    if returning:
6430        delete_expr = t.cast(
6431            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6432        )
6433    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:
6436def insert(
6437    expression: ExpOrStr,
6438    into: ExpOrStr,
6439    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6440    overwrite: t.Optional[bool] = None,
6441    returning: t.Optional[ExpOrStr] = None,
6442    dialect: DialectType = None,
6443    copy: bool = True,
6444    **opts,
6445) -> Insert:
6446    """
6447    Builds an INSERT statement.
6448
6449    Example:
6450        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6451        'INSERT INTO tbl VALUES (1, 2, 3)'
6452
6453    Args:
6454        expression: the sql string or expression of the INSERT statement
6455        into: the tbl to insert data to.
6456        columns: optionally the table's column names.
6457        overwrite: whether to INSERT OVERWRITE or not.
6458        returning: sql conditional parsed into a RETURNING statement
6459        dialect: the dialect used to parse the input expressions.
6460        copy: whether to copy the expression.
6461        **opts: other options to use to parse the input expressions.
6462
6463    Returns:
6464        Insert: the syntax tree for the INSERT statement.
6465    """
6466    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6467    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6468
6469    if columns:
6470        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6471
6472    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6473
6474    if returning:
6475        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6476
6477    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:
6480def condition(
6481    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6482) -> Condition:
6483    """
6484    Initialize a logical condition expression.
6485
6486    Example:
6487        >>> condition("x=1").sql()
6488        'x = 1'
6489
6490        This is helpful for composing larger logical syntax trees:
6491        >>> where = condition("x=1")
6492        >>> where = where.and_("y=1")
6493        >>> Select().from_("tbl").select("*").where(where).sql()
6494        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6495
6496    Args:
6497        *expression: the SQL code string to parse.
6498            If an Expression instance is passed, this is used as-is.
6499        dialect: the dialect used to parse the input expression (in the case that the
6500            input expression is a SQL string).
6501        copy: Whether to copy `expression` (only applies to expressions).
6502        **opts: other options to use to parse the input expressions (again, in the case
6503            that the input expression is a SQL string).
6504
6505    Returns:
6506        The new Condition instance
6507    """
6508    return maybe_parse(
6509        expression,
6510        into=Condition,
6511        dialect=dialect,
6512        copy=copy,
6513        **opts,
6514    )

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:
6517def and_(
6518    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6519) -> Condition:
6520    """
6521    Combine multiple conditions with an AND logical operator.
6522
6523    Example:
6524        >>> and_("x=1", and_("y=1", "z=1")).sql()
6525        'x = 1 AND (y = 1 AND z = 1)'
6526
6527    Args:
6528        *expressions: the SQL code strings to parse.
6529            If an Expression instance is passed, this is used as-is.
6530        dialect: the dialect used to parse the input expression.
6531        copy: whether to copy `expressions` (only applies to Expressions).
6532        **opts: other options to use to parse the input expressions.
6533
6534    Returns:
6535        And: the new condition
6536    """
6537    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:

And: 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:
6540def or_(
6541    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6542) -> Condition:
6543    """
6544    Combine multiple conditions with an OR logical operator.
6545
6546    Example:
6547        >>> or_("x=1", or_("y=1", "z=1")).sql()
6548        'x = 1 OR (y = 1 OR z = 1)'
6549
6550    Args:
6551        *expressions: the SQL code strings to parse.
6552            If an Expression instance is passed, this is used as-is.
6553        dialect: the dialect used to parse the input expression.
6554        copy: whether to copy `expressions` (only applies to Expressions).
6555        **opts: other options to use to parse the input expressions.
6556
6557    Returns:
6558        Or: the new condition
6559    """
6560    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:

Or: 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:
6563def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6564    """
6565    Wrap a condition with a NOT operator.
6566
6567    Example:
6568        >>> not_("this_suit='black'").sql()
6569        "NOT this_suit = 'black'"
6570
6571    Args:
6572        expression: the SQL code string to parse.
6573            If an Expression instance is passed, this is used as-is.
6574        dialect: the dialect used to parse the input expression.
6575        copy: whether to copy the expression or not.
6576        **opts: other options to use to parse the input expressions.
6577
6578    Returns:
6579        The new condition.
6580    """
6581    this = condition(
6582        expression,
6583        dialect=dialect,
6584        copy=copy,
6585        **opts,
6586    )
6587    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:
6590def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6591    """
6592    Wrap an expression in parentheses.
6593
6594    Example:
6595        >>> paren("5 + 3").sql()
6596        '(5 + 3)'
6597
6598    Args:
6599        expression: the SQL code string to parse.
6600            If an Expression instance is passed, this is used as-is.
6601        copy: whether to copy the expression or not.
6602
6603    Returns:
6604        The wrapped expression.
6605    """
6606    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):
6622def to_identifier(name, quoted=None, copy=True):
6623    """Builds an identifier.
6624
6625    Args:
6626        name: The name to turn into an identifier.
6627        quoted: Whether to force quote the identifier.
6628        copy: Whether to copy name if it's an Identifier.
6629
6630    Returns:
6631        The identifier ast node.
6632    """
6633
6634    if name is None:
6635        return None
6636
6637    if isinstance(name, Identifier):
6638        identifier = maybe_copy(name, copy)
6639    elif isinstance(name, str):
6640        identifier = Identifier(
6641            this=name,
6642            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6643        )
6644    else:
6645        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6646    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:
6649def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6650    """
6651    Parses a given string into an identifier.
6652
6653    Args:
6654        name: The name to parse into an identifier.
6655        dialect: The dialect to parse against.
6656
6657    Returns:
6658        The identifier ast node.
6659    """
6660    try:
6661        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6662    except ParseError:
6663        expression = to_identifier(name)
6664
6665    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:
6671def to_interval(interval: str | Literal) -> Interval:
6672    """Builds an interval expression from a string like '1 day' or '5 months'."""
6673    if isinstance(interval, Literal):
6674        if not interval.is_string:
6675            raise ValueError("Invalid interval string.")
6676
6677        interval = interval.this
6678
6679    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6680
6681    if not interval_parts:
6682        raise ValueError("Invalid interval string.")
6683
6684    return Interval(
6685        this=Literal.string(interval_parts.group(1)),
6686        unit=Var(this=interval_parts.group(2).upper()),
6687    )

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:
6690def to_table(
6691    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6692) -> Table:
6693    """
6694    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6695    If a table is passed in then that table is returned.
6696
6697    Args:
6698        sql_path: a `[catalog].[schema].[table]` string.
6699        dialect: the source dialect according to which the table name will be parsed.
6700        copy: Whether to copy a table if it is passed in.
6701        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6702
6703    Returns:
6704        A table expression.
6705    """
6706    if isinstance(sql_path, Table):
6707        return maybe_copy(sql_path, copy=copy)
6708
6709    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6710
6711    for k, v in kwargs.items():
6712        table.set(k, v)
6713
6714    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:
6717def to_column(
6718    sql_path: str | Column,
6719    quoted: t.Optional[bool] = None,
6720    dialect: DialectType = None,
6721    copy: bool = True,
6722    **kwargs,
6723) -> Column:
6724    """
6725    Create a column from a `[table].[column]` sql path. Table is optional.
6726    If a column is passed in then that column is returned.
6727
6728    Args:
6729        sql_path: a `[table].[column]` string.
6730        quoted: Whether or not to force quote identifiers.
6731        dialect: the source dialect according to which the column name will be parsed.
6732        copy: Whether to copy a column if it is passed in.
6733        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6734
6735    Returns:
6736        A column expression.
6737    """
6738    if isinstance(sql_path, Column):
6739        return maybe_copy(sql_path, copy=copy)
6740
6741    try:
6742        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6743    except ParseError:
6744        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6745
6746    for k, v in kwargs.items():
6747        col.set(k, v)
6748
6749    if quoted:
6750        for i in col.find_all(Identifier):
6751            i.set("quoted", True)
6752
6753    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):
6756def alias_(
6757    expression: ExpOrStr,
6758    alias: t.Optional[str | Identifier],
6759    table: bool | t.Sequence[str | Identifier] = False,
6760    quoted: t.Optional[bool] = None,
6761    dialect: DialectType = None,
6762    copy: bool = True,
6763    **opts,
6764):
6765    """Create an Alias expression.
6766
6767    Example:
6768        >>> alias_('foo', 'bar').sql()
6769        'foo AS bar'
6770
6771        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6772        '(SELECT 1, 2) AS bar(a, b)'
6773
6774    Args:
6775        expression: the SQL code strings to parse.
6776            If an Expression instance is passed, this is used as-is.
6777        alias: the alias name to use. If the name has
6778            special characters it is quoted.
6779        table: Whether to create a table alias, can also be a list of columns.
6780        quoted: whether to quote the alias
6781        dialect: the dialect used to parse the input expression.
6782        copy: Whether to copy the expression.
6783        **opts: other options to use to parse the input expressions.
6784
6785    Returns:
6786        Alias: the aliased expression
6787    """
6788    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6789    alias = to_identifier(alias, quoted=quoted)
6790
6791    if table:
6792        table_alias = TableAlias(this=alias)
6793        exp.set("alias", table_alias)
6794
6795        if not isinstance(table, bool):
6796            for column in table:
6797                table_alias.append("columns", to_identifier(column, quoted=quoted))
6798
6799        return exp
6800
6801    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6802    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6803    # for the complete Window expression.
6804    #
6805    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6806
6807    if "alias" in exp.arg_types and not isinstance(exp, Window):
6808        exp.set("alias", alias)
6809        return exp
6810    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:
6813def subquery(
6814    expression: ExpOrStr,
6815    alias: t.Optional[Identifier | str] = None,
6816    dialect: DialectType = None,
6817    **opts,
6818) -> Select:
6819    """
6820    Build a subquery expression that's selected from.
6821
6822    Example:
6823        >>> subquery('select x from tbl', 'bar').select('x').sql()
6824        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6825
6826    Args:
6827        expression: the SQL code strings to parse.
6828            If an Expression instance is passed, this is used as-is.
6829        alias: the alias name to use.
6830        dialect: the dialect used to parse the input expression.
6831        **opts: other options to use to parse the input expressions.
6832
6833    Returns:
6834        A new Select instance with the subquery expression included.
6835    """
6836
6837    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
6838    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):
6869def column(
6870    col,
6871    table=None,
6872    db=None,
6873    catalog=None,
6874    *,
6875    fields=None,
6876    quoted=None,
6877    copy=True,
6878):
6879    """
6880    Build a Column.
6881
6882    Args:
6883        col: Column name.
6884        table: Table name.
6885        db: Database name.
6886        catalog: Catalog name.
6887        fields: Additional fields using dots.
6888        quoted: Whether to force quotes on the column's identifiers.
6889        copy: Whether to copy identifiers if passed in.
6890
6891    Returns:
6892        The new Column instance.
6893    """
6894    this = Column(
6895        this=to_identifier(col, quoted=quoted, copy=copy),
6896        table=to_identifier(table, quoted=quoted, copy=copy),
6897        db=to_identifier(db, quoted=quoted, copy=copy),
6898        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6899    )
6900
6901    if fields:
6902        this = Dot.build(
6903            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
6904        )
6905    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:
6908def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6909    """Cast an expression to a data type.
6910
6911    Example:
6912        >>> cast('x + 1', 'int').sql()
6913        'CAST(x + 1 AS INT)'
6914
6915    Args:
6916        expression: The expression to cast.
6917        to: The datatype to cast to.
6918        copy: Whether to copy the supplied expressions.
6919
6920    Returns:
6921        The new Cast instance.
6922    """
6923    expr = maybe_parse(expression, copy=copy, **opts)
6924    data_type = DataType.build(to, copy=copy, **opts)
6925
6926    if expr.is_type(data_type):
6927        return expr
6928
6929    expr = Cast(this=expr, to=data_type)
6930    expr.type = data_type
6931
6932    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:
6935def table_(
6936    table: Identifier | str,
6937    db: t.Optional[Identifier | str] = None,
6938    catalog: t.Optional[Identifier | str] = None,
6939    quoted: t.Optional[bool] = None,
6940    alias: t.Optional[Identifier | str] = None,
6941) -> Table:
6942    """Build a Table.
6943
6944    Args:
6945        table: Table name.
6946        db: Database name.
6947        catalog: Catalog name.
6948        quote: Whether to force quotes on the table's identifiers.
6949        alias: Table's alias.
6950
6951    Returns:
6952        The new Table instance.
6953    """
6954    return Table(
6955        this=to_identifier(table, quoted=quoted) if table else None,
6956        db=to_identifier(db, quoted=quoted) if db else None,
6957        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6958        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6959    )

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:
6962def values(
6963    values: t.Iterable[t.Tuple[t.Any, ...]],
6964    alias: t.Optional[str] = None,
6965    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6966) -> Values:
6967    """Build VALUES statement.
6968
6969    Example:
6970        >>> values([(1, '2')]).sql()
6971        "VALUES (1, '2')"
6972
6973    Args:
6974        values: values statements that will be converted to SQL
6975        alias: optional alias
6976        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6977         If either are provided then an alias is also required.
6978
6979    Returns:
6980        Values: the Values expression object
6981    """
6982    if columns and not alias:
6983        raise ValueError("Alias is required when providing columns")
6984
6985    return Values(
6986        expressions=[convert(tup) for tup in values],
6987        alias=(
6988            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6989            if columns
6990            else (TableAlias(this=to_identifier(alias)) if alias else None)
6991        ),
6992    )

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:
6995def var(name: t.Optional[ExpOrStr]) -> Var:
6996    """Build a SQL variable.
6997
6998    Example:
6999        >>> repr(var('x'))
7000        'Var(this=x)'
7001
7002        >>> repr(var(column('x', table='y')))
7003        'Var(this=x)'
7004
7005    Args:
7006        name: The name of the var or an expression who's name will become the var.
7007
7008    Returns:
7009        The new variable node.
7010    """
7011    if not name:
7012        raise ValueError("Cannot convert empty name into var.")
7013
7014    if isinstance(name, Expression):
7015        name = name.name
7016    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:
7019def rename_table(
7020    old_name: str | Table,
7021    new_name: str | Table,
7022    dialect: DialectType = None,
7023) -> AlterTable:
7024    """Build ALTER TABLE... RENAME... expression
7025
7026    Args:
7027        old_name: The old name of the table
7028        new_name: The new name of the table
7029        dialect: The dialect to parse the table.
7030
7031    Returns:
7032        Alter table expression
7033    """
7034    old_table = to_table(old_name, dialect=dialect)
7035    new_table = to_table(new_name, dialect=dialect)
7036    return AlterTable(
7037        this=old_table,
7038        actions=[
7039            RenameTable(this=new_table),
7040        ],
7041    )

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:
7044def rename_column(
7045    table_name: str | Table,
7046    old_column_name: str | Column,
7047    new_column_name: str | Column,
7048    exists: t.Optional[bool] = None,
7049    dialect: DialectType = None,
7050) -> AlterTable:
7051    """Build ALTER TABLE... RENAME COLUMN... expression
7052
7053    Args:
7054        table_name: Name of the table
7055        old_column: The old name of the column
7056        new_column: The new name of the column
7057        exists: Whether to add the `IF EXISTS` clause
7058        dialect: The dialect to parse the table/column.
7059
7060    Returns:
7061        Alter table expression
7062    """
7063    table = to_table(table_name, dialect=dialect)
7064    old_column = to_column(old_column_name, dialect=dialect)
7065    new_column = to_column(new_column_name, dialect=dialect)
7066    return AlterTable(
7067        this=table,
7068        actions=[
7069            RenameColumn(this=old_column, to=new_column, exists=exists),
7070        ],
7071    )

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:
7074def convert(value: t.Any, copy: bool = False) -> Expression:
7075    """Convert a python value into an expression object.
7076
7077    Raises an error if a conversion is not possible.
7078
7079    Args:
7080        value: A python object.
7081        copy: Whether to copy `value` (only applies to Expressions and collections).
7082
7083    Returns:
7084        The equivalent expression object.
7085    """
7086    if isinstance(value, Expression):
7087        return maybe_copy(value, copy)
7088    if isinstance(value, str):
7089        return Literal.string(value)
7090    if isinstance(value, bool):
7091        return Boolean(this=value)
7092    if value is None or (isinstance(value, float) and math.isnan(value)):
7093        return null()
7094    if isinstance(value, numbers.Number):
7095        return Literal.number(value)
7096    if isinstance(value, bytes):
7097        return HexString(this=value.hex())
7098    if isinstance(value, datetime.datetime):
7099        datetime_literal = Literal.string(
7100            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7101                sep=" "
7102            )
7103        )
7104        return TimeStrToTime(this=datetime_literal)
7105    if isinstance(value, datetime.date):
7106        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7107        return DateStrToDate(this=date_literal)
7108    if isinstance(value, tuple):
7109        if hasattr(value, "_fields"):
7110            return Struct(
7111                expressions=[
7112                    PropertyEQ(
7113                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7114                    )
7115                    for k in value._fields
7116                ]
7117            )
7118        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7119    if isinstance(value, list):
7120        return Array(expressions=[convert(v, copy=copy) for v in value])
7121    if isinstance(value, dict):
7122        return Map(
7123            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7124            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7125        )
7126    if hasattr(value, "__dict__"):
7127        return Struct(
7128            expressions=[
7129                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7130                for k, v in value.__dict__.items()
7131            ]
7132        )
7133    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:
7136def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7137    """
7138    Replace children of an expression with the result of a lambda fun(child) -> exp.
7139    """
7140    for k, v in tuple(expression.args.items()):
7141        is_list_arg = type(v) is list
7142
7143        child_nodes = v if is_list_arg else [v]
7144        new_child_nodes = []
7145
7146        for cn in child_nodes:
7147            if isinstance(cn, Expression):
7148                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7149                    new_child_nodes.append(child_node)
7150            else:
7151                new_child_nodes.append(cn)
7152
7153        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:
7156def replace_tree(
7157    expression: Expression,
7158    fun: t.Callable,
7159    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7160) -> Expression:
7161    """
7162    Replace an entire tree with the result of function calls on each node.
7163
7164    This will be traversed in reverse dfs, so leaves first.
7165    If new nodes are created as a result of function calls, they will also be traversed.
7166    """
7167    stack = list(expression.dfs(prune=prune))
7168
7169    while stack:
7170        node = stack.pop()
7171        new_node = fun(node)
7172
7173        if new_node is not node:
7174            node.replace(new_node)
7175
7176            if isinstance(new_node, Expression):
7177                stack.append(new_node)
7178
7179    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]:
7182def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7183    """
7184    Return all table names referenced through columns in an expression.
7185
7186    Example:
7187        >>> import sqlglot
7188        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7189        ['a', 'c']
7190
7191    Args:
7192        expression: expression to find table names.
7193        exclude: a table name to exclude
7194
7195    Returns:
7196        A list of unique names.
7197    """
7198    return {
7199        table
7200        for table in (column.table for column in expression.find_all(Column))
7201        if table and table != exclude
7202    }

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:
7205def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7206    """Get the full name of a table as a string.
7207
7208    Args:
7209        table: Table expression node or string.
7210        dialect: The dialect to generate the table name for.
7211        identify: Determines when an identifier should be quoted. Possible values are:
7212            False (default): Never quote, except in cases where it's mandatory by the dialect.
7213            True: Always quote.
7214
7215    Examples:
7216        >>> from sqlglot import exp, parse_one
7217        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7218        'a.b.c'
7219
7220    Returns:
7221        The table name.
7222    """
7223
7224    table = maybe_parse(table, into=Table, dialect=dialect)
7225
7226    if not table:
7227        raise ValueError(f"Cannot parse {table}")
7228
7229    return ".".join(
7230        (
7231            part.sql(dialect=dialect, identify=True, copy=False)
7232            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7233            else part.name
7234        )
7235        for part in table.parts
7236    )

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:
7239def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7240    """Returns a case normalized table name without quotes.
7241
7242    Args:
7243        table: the table to normalize
7244        dialect: the dialect to use for normalization rules
7245        copy: whether to copy the expression.
7246
7247    Examples:
7248        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7249        'A-B.c'
7250    """
7251    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7252
7253    return ".".join(
7254        p.name
7255        for p in normalize_identifiers(
7256            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7257        ).parts
7258    )

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:
7261def replace_tables(
7262    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7263) -> E:
7264    """Replace all tables in expression according to the mapping.
7265
7266    Args:
7267        expression: expression node to be transformed and replaced.
7268        mapping: mapping of table names.
7269        dialect: the dialect of the mapping table
7270        copy: whether to copy the expression.
7271
7272    Examples:
7273        >>> from sqlglot import exp, parse_one
7274        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7275        'SELECT * FROM c /* a.b */'
7276
7277    Returns:
7278        The mapped expression.
7279    """
7280
7281    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7282
7283    def _replace_tables(node: Expression) -> Expression:
7284        if isinstance(node, Table):
7285            original = normalize_table_name(node, dialect=dialect)
7286            new_name = mapping.get(original)
7287
7288            if new_name:
7289                table = to_table(
7290                    new_name,
7291                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7292                    dialect=dialect,
7293                )
7294                table.add_comments([original])
7295                return table
7296        return node
7297
7298    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:
7301def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7302    """Replace placeholders in an expression.
7303
7304    Args:
7305        expression: expression node to be transformed and replaced.
7306        args: positional names that will substitute unnamed placeholders in the given order.
7307        kwargs: keyword arguments that will substitute named placeholders.
7308
7309    Examples:
7310        >>> from sqlglot import exp, parse_one
7311        >>> replace_placeholders(
7312        ...     parse_one("select * from :tbl where ? = ?"),
7313        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7314        ... ).sql()
7315        "SELECT * FROM foo WHERE str_col = 'b'"
7316
7317    Returns:
7318        The mapped expression.
7319    """
7320
7321    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7322        if isinstance(node, Placeholder):
7323            if node.this:
7324                new_name = kwargs.get(node.this)
7325                if new_name is not None:
7326                    return convert(new_name)
7327            else:
7328                try:
7329                    return convert(next(args))
7330                except StopIteration:
7331                    pass
7332        return node
7333
7334    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:
7337def expand(
7338    expression: Expression,
7339    sources: t.Dict[str, Query],
7340    dialect: DialectType = None,
7341    copy: bool = True,
7342) -> Expression:
7343    """Transforms an expression by expanding all referenced sources into subqueries.
7344
7345    Examples:
7346        >>> from sqlglot import parse_one
7347        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7348        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7349
7350        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7351        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7352
7353    Args:
7354        expression: The expression to expand.
7355        sources: A dictionary of name to Queries.
7356        dialect: The dialect of the sources dict.
7357        copy: Whether to copy the expression during transformation. Defaults to True.
7358
7359    Returns:
7360        The transformed expression.
7361    """
7362    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7363
7364    def _expand(node: Expression):
7365        if isinstance(node, Table):
7366            name = normalize_table_name(node, dialect=dialect)
7367            source = sources.get(name)
7368            if source:
7369                subquery = source.subquery(node.alias or name)
7370                subquery.comments = [f"source: {name}"]
7371                return subquery.transform(_expand, copy=False)
7372        return node
7373
7374    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:
7377def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7378    """
7379    Returns a Func expression.
7380
7381    Examples:
7382        >>> func("abs", 5).sql()
7383        'ABS(5)'
7384
7385        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7386        'CAST(5 AS DOUBLE)'
7387
7388    Args:
7389        name: the name of the function to build.
7390        args: the args used to instantiate the function of interest.
7391        copy: whether to copy the argument expressions.
7392        dialect: the source dialect.
7393        kwargs: the kwargs used to instantiate the function of interest.
7394
7395    Note:
7396        The arguments `args` and `kwargs` are mutually exclusive.
7397
7398    Returns:
7399        An instance of the function of interest, or an anonymous function, if `name` doesn't
7400        correspond to an existing `sqlglot.expressions.Func` class.
7401    """
7402    if args and kwargs:
7403        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7404
7405    from sqlglot.dialects.dialect import Dialect
7406
7407    dialect = Dialect.get_or_raise(dialect)
7408
7409    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7410    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7411
7412    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7413    if constructor:
7414        if converted:
7415            if "dialect" in constructor.__code__.co_varnames:
7416                function = constructor(converted, dialect=dialect)
7417            else:
7418                function = constructor(converted)
7419        elif constructor.__name__ == "from_arg_list":
7420            function = constructor.__self__(**kwargs)  # type: ignore
7421        else:
7422            constructor = FUNCTION_BY_NAME.get(name.upper())
7423            if constructor:
7424                function = constructor(**kwargs)
7425            else:
7426                raise ValueError(
7427                    f"Unable to convert '{name}' into a Func. Either manually construct "
7428                    "the Func expression of interest or parse the function call."
7429                )
7430    else:
7431        kwargs = kwargs or {"expressions": converted}
7432        function = Anonymous(this=name, **kwargs)
7433
7434    for error_message in function.error_messages(converted):
7435        raise ValueError(error_message)
7436
7437    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:
7440def case(
7441    expression: t.Optional[ExpOrStr] = None,
7442    **opts,
7443) -> Case:
7444    """
7445    Initialize a CASE statement.
7446
7447    Example:
7448        case().when("a = 1", "foo").else_("bar")
7449
7450    Args:
7451        expression: Optionally, the input expression (not all dialects support this)
7452        **opts: Extra keyword arguments for parsing `expression`
7453    """
7454    if expression is not None:
7455        this = maybe_parse(expression, **opts)
7456    else:
7457        this = None
7458    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:
7461def array(
7462    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7463) -> Array:
7464    """
7465    Returns an array.
7466
7467    Examples:
7468        >>> array(1, 'x').sql()
7469        'ARRAY(1, x)'
7470
7471    Args:
7472        expressions: the expressions to add to the array.
7473        copy: whether to copy the argument expressions.
7474        dialect: the source dialect.
7475        kwargs: the kwargs used to instantiate the function of interest.
7476
7477    Returns:
7478        An array expression.
7479    """
7480    return Array(
7481        expressions=[
7482            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7483            for expression in expressions
7484        ]
7485    )

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:
7488def tuple_(
7489    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7490) -> Tuple:
7491    """
7492    Returns an tuple.
7493
7494    Examples:
7495        >>> tuple_(1, 'x').sql()
7496        '(1, x)'
7497
7498    Args:
7499        expressions: the expressions to add to the tuple.
7500        copy: whether to copy the argument expressions.
7501        dialect: the source dialect.
7502        kwargs: the kwargs used to instantiate the function of interest.
7503
7504    Returns:
7505        A tuple expression.
7506    """
7507    return Tuple(
7508        expressions=[
7509            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7510            for expression in expressions
7511        ]
7512    )

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:
7515def true() -> Boolean:
7516    """
7517    Returns a true Boolean expression.
7518    """
7519    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7522def false() -> Boolean:
7523    """
7524    Returns a false Boolean expression.
7525    """
7526    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7529def null() -> Null:
7530    """
7531    Returns a Null expression.
7532    """
7533    return Null()

Returns a Null expression.

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