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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

expressions: List[Any]
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 []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
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 ""

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
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"]

Checks whether a Literal expression is a string.

is_number: bool
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"]

Checks whether a Literal expression is a number.

is_int: bool
179    @property
180    def is_int(self) -> bool:
181        """
182        Checks whether a Literal expression is an integer.
183        """
184        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
186    @property
187    def is_star(self) -> bool:
188        """Checks whether an expression is a star."""
189        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
191    @property
192    def alias(self) -> str:
193        """
194        Returns the alias of the expression, or an empty string if it's not aliased.
195        """
196        if isinstance(self.args.get("alias"), TableAlias):
197            return self.args["alias"].name
198        return self.text("alias")

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

alias_column_names: List[str]
200    @property
201    def alias_column_names(self) -> t.List[str]:
202        table_alias = self.args.get("alias")
203        if not table_alias:
204            return []
205        return [c.name for c in table_alias.args.get("columns") or []]
name: str
207    @property
208    def name(self) -> str:
209        return self.text("this")
alias_or_name: str
211    @property
212    def alias_or_name(self) -> str:
213        return self.alias or self.name
output_name: str
215    @property
216    def output_name(self) -> str:
217        """
218        Name of the output column if this expression is a selection.
219
220        If the Expression has no output name, an empty string is returned.
221
222        Example:
223            >>> from sqlglot import parse_one
224            >>> parse_one("SELECT a").expressions[0].output_name
225            'a'
226            >>> parse_one("SELECT b AS c").expressions[0].output_name
227            'c'
228            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
229            ''
230        """
231        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]
233    @property
234    def type(self) -> t.Optional[DataType]:
235        return self._type
def is_type(self, *dtypes) -> bool:
243    def is_type(self, *dtypes) -> bool:
244        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
246    def is_leaf(self) -> bool:
247        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
249    @property
250    def meta(self) -> t.Dict[str, t.Any]:
251        if self._meta is None:
252            self._meta = {}
253        return self._meta
def copy(self):
289    def copy(self):
290        """
291        Returns a deep copy of the expression.
292        """
293        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
295    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
296        if self.comments is None:
297            self.comments = []
298        if comments:
299            for comment in comments:
300                _, *meta = comment.split(SQLGLOT_META)
301                if meta:
302                    for kv in "".join(meta).split(","):
303                        k, *v = kv.split("=")
304                        value = v[0].strip() if v else True
305                        self.meta[k.strip()] = value
306                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
308    def append(self, arg_key: str, value: t.Any) -> None:
309        """
310        Appends value to arg_key if it's a list or sets it as a new list.
311
312        Args:
313            arg_key (str): name of the list expression arg
314            value (Any): value to append to the list
315        """
316        if type(self.args.get(arg_key)) is not list:
317            self.args[arg_key] = []
318        self._set_parent(arg_key, value)
319        values = self.args[arg_key]
320        if hasattr(value, "parent"):
321            value.index = len(values)
322        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) -> None:
324    def set(self, arg_key: str, value: t.Any) -> None:
325        """
326        Sets arg_key to value.
327
328        Args:
329            arg_key: name of the expression arg.
330            value: value to set the arg to.
331        """
332        if value is None:
333            self.args.pop(arg_key, None)
334        else:
335            self.args[arg_key] = value
336            self._set_parent(arg_key, value)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
depth: int
350    @property
351    def depth(self) -> int:
352        """
353        Returns the depth of this tree.
354        """
355        if self.parent:
356            return self.parent.depth + 1
357        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
359    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
360        """Yields the key and expression for all arguments, exploding list args."""
361        # remove tuple when python 3.7 is deprecated
362        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
363            if type(vs) is list:
364                for v in reversed(vs) if reverse else vs:
365                    if hasattr(v, "parent"):
366                        yield v
367            else:
368                if hasattr(vs, "parent"):
369                    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]:
371    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
372        """
373        Returns the first node in this tree which matches at least one of
374        the specified types.
375
376        Args:
377            expression_types: the expression type(s) to match.
378            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
379
380        Returns:
381            The node which matches the criteria or None if no such node was found.
382        """
383        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]:
385    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
386        """
387        Returns a generator object which visits all nodes in this tree and only
388        yields those that match at least one of the specified expression types.
389
390        Args:
391            expression_types: the expression type(s) to match.
392            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
393
394        Returns:
395            The generator object.
396        """
397        for expression in self.walk(bfs=bfs):
398            if isinstance(expression, expression_types):
399                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]:
401    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
402        """
403        Returns a nearest parent matching expression_types.
404
405        Args:
406            expression_types: the expression type(s) to match.
407
408        Returns:
409            The parent node.
410        """
411        ancestor = self.parent
412        while ancestor and not isinstance(ancestor, expression_types):
413            ancestor = ancestor.parent
414        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]
416    @property
417    def parent_select(self) -> t.Optional[Select]:
418        """
419        Returns the parent select statement.
420        """
421        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
423    @property
424    def same_parent(self) -> bool:
425        """Returns if the parent is the same class as itself."""
426        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
428    def root(self) -> Expression:
429        """
430        Returns the root expression of this tree.
431        """
432        expression = self
433        while expression.parent:
434            expression = expression.parent
435        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
437    def walk(
438        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
439    ) -> t.Iterator[Expression]:
440        """
441        Returns a generator object which visits all nodes in this tree.
442
443        Args:
444            bfs (bool): if set to True the BFS traversal order will be applied,
445                otherwise the DFS traversal will be used instead.
446            prune ((node, parent, arg_key) -> bool): callable that returns True if
447                the generator should stop traversing this branch of the tree.
448
449        Returns:
450            the generator object.
451        """
452        if bfs:
453            yield from self.bfs(prune=prune)
454        else:
455            yield from self.dfs(prune=prune)

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs (bool): if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune ((node, parent, arg_key) -> bool): 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]:
457    def dfs(
458        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
459    ) -> t.Iterator[Expression]:
460        """
461        Returns a generator object which visits all nodes in this tree in
462        the DFS (Depth-first) order.
463
464        Returns:
465            The generator object.
466        """
467        stack = [self]
468
469        while stack:
470            node = stack.pop()
471
472            yield node
473
474            if prune and prune(node):
475                continue
476
477            for v in node.iter_expressions(reverse=True):
478                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]:
480    def bfs(
481        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
482    ) -> t.Iterator[Expression]:
483        """
484        Returns a generator object which visits all nodes in this tree in
485        the BFS (Breadth-first) order.
486
487        Returns:
488            The generator object.
489        """
490        queue = deque([self])
491
492        while queue:
493            node = queue.popleft()
494
495            yield node
496
497            if prune and prune(node):
498                continue
499
500            for v in node.iter_expressions():
501                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):
503    def unnest(self):
504        """
505        Returns the first non parenthesis child or self.
506        """
507        expression = self
508        while type(expression) is Paren:
509            expression = expression.this
510        return expression

Returns the first non parenthesis child or self.

def unalias(self):
512    def unalias(self):
513        """
514        Returns the inner expression if this is an Alias.
515        """
516        if isinstance(self, Alias):
517            return self.this
518        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
520    def unnest_operands(self):
521        """
522        Returns unnested operands as a tuple.
523        """
524        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
526    def flatten(self, unnest=True):
527        """
528        Returns a generator which yields child nodes whose parents are the same class.
529
530        A AND B AND C -> [A, B, C]
531        """
532        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
533            if type(node) is not self.__class__:
534                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:
542    def to_s(self) -> str:
543        """
544        Same as __repr__, but includes additional information which can be useful
545        for debugging, like empty or missing args and the AST nodes' object IDs.
546        """
547        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:
549    def sql(self, dialect: DialectType = None, **opts) -> str:
550        """
551        Returns SQL string representation of this tree.
552
553        Args:
554            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
555            opts: other `sqlglot.generator.Generator` options.
556
557        Returns:
558            The SQL string.
559        """
560        from sqlglot.dialects import Dialect
561
562        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:
564    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
565        """
566        Visits all tree nodes (excluding already transformed ones)
567        and applies the given transformation function to each node.
568
569        Args:
570            fun (function): a function which takes a node as an argument and returns a
571                new transformed node or the same node without modifications. If the function
572                returns None, then the corresponding node will be removed from the syntax tree.
573            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
574                modified in place.
575
576        Returns:
577            The transformed tree.
578        """
579        root = None
580        new_node = None
581
582        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
583            new_node = fun(node, *args, **kwargs)
584
585            if root:
586                if new_node is not node:
587                    node.replace(new_node)
588            else:
589                root = new_node
590
591        assert root
592        return root.assert_is(Expression)

Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun (function): 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 (bool): 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):
600    def replace(self, expression):
601        """
602        Swap out this expression with a new expression.
603
604        For example::
605
606            >>> tree = Select().select("x").from_("tbl")
607            >>> tree.find(Column).replace(column("y"))
608            Column(
609              this=Identifier(this=y, quoted=False))
610            >>> tree.sql()
611            'SELECT y FROM tbl'
612
613        Args:
614            expression: new node
615
616        Returns:
617            The new expression or expressions.
618        """
619        parent = self.parent
620
621        if not parent:
622            return expression
623
624        key = self.arg_key
625        value = parent.args.get(key)
626
627        if isinstance(value, list):
628            index = self.index
629
630            if isinstance(expression, list):
631                value.pop(index)
632                value[index:index] = expression
633                parent._set_parent(key, value)
634            else:
635                if expression is None:
636                    value.pop(index)
637
638                    for v in value[index:]:
639                        v.index = v.index - 1
640                else:
641                    value[index] = expression
642                    parent._set_parent(key, expression, index=index)
643        elif value is not None:
644            if expression is None:
645                parent.args.pop(key)
646            else:
647                parent.set(key, expression)
648
649        if expression is not self:
650            self.parent = None
651            self.arg_key = None
652            self.index = None
653
654        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:
656    def pop(self: E) -> E:
657        """
658        Remove this expression from its AST.
659
660        Returns:
661            The popped expression.
662        """
663        self.replace(None)
664        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
726    @classmethod
727    def load(cls, obj):
728        """
729        Load a dict (as returned by `Expression.dump`) into an Expression instance.
730        """
731        from sqlglot.serde import load
732
733        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:
735    def and_(
736        self,
737        *expressions: t.Optional[ExpOrStr],
738        dialect: DialectType = None,
739        copy: bool = True,
740        **opts,
741    ) -> Condition:
742        """
743        AND this condition with one or multiple expressions.
744
745        Example:
746            >>> condition("x=1").and_("y=1").sql()
747            'x = 1 AND y = 1'
748
749        Args:
750            *expressions: the SQL code strings to parse.
751                If an `Expression` instance is passed, it will be used as-is.
752            dialect: the dialect used to parse the input expression.
753            copy: whether to copy the involved expressions (only applies to Expressions).
754            opts: other options to use to parse the input expressions.
755
756        Returns:
757            The new And condition.
758        """
759        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:
761    def or_(
762        self,
763        *expressions: t.Optional[ExpOrStr],
764        dialect: DialectType = None,
765        copy: bool = True,
766        **opts,
767    ) -> Condition:
768        """
769        OR this condition with one or multiple expressions.
770
771        Example:
772            >>> condition("x=1").or_("y=1").sql()
773            'x = 1 OR y = 1'
774
775        Args:
776            *expressions: the SQL code strings to parse.
777                If an `Expression` instance is passed, it will be used as-is.
778            dialect: the dialect used to parse the input expression.
779            copy: whether to copy the involved expressions (only applies to Expressions).
780            opts: other options to use to parse the input expressions.
781
782        Returns:
783            The new Or condition.
784        """
785        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):
787    def not_(self, copy: bool = True):
788        """
789        Wrap this condition with NOT.
790
791        Example:
792            >>> condition("x=1").not_().sql()
793            'NOT x = 1'
794
795        Args:
796            copy: whether to copy this object.
797
798        Returns:
799            The new Not instance.
800        """
801        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:
803    def as_(
804        self,
805        alias: str | Identifier,
806        quoted: t.Optional[bool] = None,
807        dialect: DialectType = None,
808        copy: bool = True,
809        **opts,
810    ) -> Alias:
811        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:
836    def isin(
837        self,
838        *expressions: t.Any,
839        query: t.Optional[ExpOrStr] = None,
840        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
841        copy: bool = True,
842        **opts,
843    ) -> In:
844        return In(
845            this=maybe_copy(self, copy),
846            expressions=[convert(e, copy=copy) for e in expressions],
847            query=maybe_parse(query, copy=copy, **opts) if query else None,
848            unnest=(
849                Unnest(
850                    expressions=[
851                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
852                        for e in ensure_list(unnest)
853                    ]
854                )
855                if unnest
856                else None
857            ),
858        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
860    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
861        return Between(
862            this=maybe_copy(self, copy),
863            low=convert(low, copy=copy, **opts),
864            high=convert(high, copy=copy, **opts),
865        )
def is_( self, other: Union[str, Expression]) -> Is:
867    def is_(self, other: ExpOrStr) -> Is:
868        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
870    def like(self, other: ExpOrStr) -> Like:
871        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
873    def ilike(self, other: ExpOrStr) -> ILike:
874        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
876    def eq(self, other: t.Any) -> EQ:
877        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
879    def neq(self, other: t.Any) -> NEQ:
880        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
882    def rlike(self, other: ExpOrStr) -> RegexpLike:
883        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
885    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
886        div = self._binop(Div, other)
887        div.args["typed"] = typed
888        div.args["safe"] = safe
889        return div
def desc(self, nulls_first: bool = False) -> Ordered:
891    def desc(self, nulls_first: bool = False) -> Ordered:
892        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):
975class Condition(Expression):
976    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
983class DerivedTable(Expression):
984    @property
985    def selects(self) -> t.List[Expression]:
986        return self.this.selects if isinstance(self.this, Query) else []
987
988    @property
989    def named_selects(self) -> t.List[str]:
990        return [select.output_name for select in self.selects]
selects: List[Expression]
984    @property
985    def selects(self) -> t.List[Expression]:
986        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
988    @property
989    def named_selects(self) -> t.List[str]:
990        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
 993class Query(Expression):
 994    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
 995        """
 996        Returns a `Subquery` that wraps around this query.
 997
 998        Example:
 999            >>> subquery = Select().select("x").from_("tbl").subquery()
1000            >>> Select().select("x").from_(subquery).sql()
1001            'SELECT x FROM (SELECT x FROM tbl)'
1002
1003        Args:
1004            alias: an optional alias for the subquery.
1005            copy: if `False`, modify this expression instance in-place.
1006        """
1007        instance = maybe_copy(self, copy)
1008        if not isinstance(alias, Expression):
1009            alias = TableAlias(this=to_identifier(alias)) if alias else None
1010
1011        return Subquery(this=instance, alias=alias)
1012
1013    def limit(
1014        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1015    ) -> Select:
1016        """
1017        Adds a LIMIT clause to this query.
1018
1019        Example:
1020            >>> select("1").union(select("1")).limit(1).sql()
1021            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
1022
1023        Args:
1024            expression: the SQL code string to parse.
1025                This can also be an integer.
1026                If a `Limit` instance is passed, it will be used as-is.
1027                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1028            dialect: the dialect used to parse the input expression.
1029            copy: if `False`, modify this expression instance in-place.
1030            opts: other options to use to parse the input expressions.
1031
1032        Returns:
1033            A limited Select expression.
1034        """
1035        return (
1036            select("*")
1037            .from_(self.subquery(alias="_l_0", copy=copy))
1038            .limit(expression, dialect=dialect, copy=False, **opts)
1039        )
1040
1041    @property
1042    def ctes(self) -> t.List[CTE]:
1043        """Returns a list of all the CTEs attached to this query."""
1044        with_ = self.args.get("with")
1045        return with_.expressions if with_ else []
1046
1047    @property
1048    def selects(self) -> t.List[Expression]:
1049        """Returns the query's projections."""
1050        raise NotImplementedError("Query objects must implement `selects`")
1051
1052    @property
1053    def named_selects(self) -> t.List[str]:
1054        """Returns the output names of the query's projections."""
1055        raise NotImplementedError("Query objects must implement `named_selects`")
1056
1057    def select(
1058        self: Q,
1059        *expressions: t.Optional[ExpOrStr],
1060        append: bool = True,
1061        dialect: DialectType = None,
1062        copy: bool = True,
1063        **opts,
1064    ) -> Q:
1065        """
1066        Append to or set the SELECT expressions.
1067
1068        Example:
1069            >>> Select().select("x", "y").sql()
1070            'SELECT x, y'
1071
1072        Args:
1073            *expressions: the SQL code strings to parse.
1074                If an `Expression` instance is passed, it will be used as-is.
1075            append: if `True`, add to any existing expressions.
1076                Otherwise, this resets the expressions.
1077            dialect: the dialect used to parse the input expressions.
1078            copy: if `False`, modify this expression instance in-place.
1079            opts: other options to use to parse the input expressions.
1080
1081        Returns:
1082            The modified Query expression.
1083        """
1084        raise NotImplementedError("Query objects must implement `select`")
1085
1086    def with_(
1087        self: Q,
1088        alias: ExpOrStr,
1089        as_: ExpOrStr,
1090        recursive: t.Optional[bool] = None,
1091        append: bool = True,
1092        dialect: DialectType = None,
1093        copy: bool = True,
1094        **opts,
1095    ) -> Q:
1096        """
1097        Append to or set the common table expressions.
1098
1099        Example:
1100            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1101            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1102
1103        Args:
1104            alias: the SQL code string to parse as the table name.
1105                If an `Expression` instance is passed, this is used as-is.
1106            as_: the SQL code string to parse as the table expression.
1107                If an `Expression` instance is passed, it will be used as-is.
1108            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1109            append: if `True`, add to any existing expressions.
1110                Otherwise, this resets the expressions.
1111            dialect: the dialect used to parse the input expression.
1112            copy: if `False`, modify this expression instance in-place.
1113            opts: other options to use to parse the input expressions.
1114
1115        Returns:
1116            The modified expression.
1117        """
1118        return _apply_cte_builder(
1119            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1120        )
1121
1122    def union(
1123        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1124    ) -> Union:
1125        """
1126        Builds a UNION expression.
1127
1128        Example:
1129            >>> import sqlglot
1130            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1131            'SELECT * FROM foo UNION SELECT * FROM bla'
1132
1133        Args:
1134            expression: the SQL code string.
1135                If an `Expression` instance is passed, it will be used as-is.
1136            distinct: set the DISTINCT flag if and only if this is true.
1137            dialect: the dialect used to parse the input expression.
1138            opts: other options to use to parse the input expressions.
1139
1140        Returns:
1141            The new Union expression.
1142        """
1143        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1144
1145    def intersect(
1146        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1147    ) -> Intersect:
1148        """
1149        Builds an INTERSECT expression.
1150
1151        Example:
1152            >>> import sqlglot
1153            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1154            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1155
1156        Args:
1157            expression: the SQL code string.
1158                If an `Expression` instance is passed, it will be used as-is.
1159            distinct: set the DISTINCT flag if and only if this is true.
1160            dialect: the dialect used to parse the input expression.
1161            opts: other options to use to parse the input expressions.
1162
1163        Returns:
1164            The new Intersect expression.
1165        """
1166        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1167
1168    def except_(
1169        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1170    ) -> Except:
1171        """
1172        Builds an EXCEPT expression.
1173
1174        Example:
1175            >>> import sqlglot
1176            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1177            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1178
1179        Args:
1180            expression: the SQL code string.
1181                If an `Expression` instance is passed, it will be used as-is.
1182            distinct: set the DISTINCT flag if and only if this is true.
1183            dialect: the dialect used to parse the input expression.
1184            opts: other options to use to parse the input expressions.
1185
1186        Returns:
1187            The new Except expression.
1188        """
1189        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
 994    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
 995        """
 996        Returns a `Subquery` that wraps around this query.
 997
 998        Example:
 999            >>> subquery = Select().select("x").from_("tbl").subquery()
1000            >>> Select().select("x").from_(subquery).sql()
1001            'SELECT x FROM (SELECT x FROM tbl)'
1002
1003        Args:
1004            alias: an optional alias for the subquery.
1005            copy: if `False`, modify this expression instance in-place.
1006        """
1007        instance = maybe_copy(self, copy)
1008        if not isinstance(alias, Expression):
1009            alias = TableAlias(this=to_identifier(alias)) if alias else None
1010
1011        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, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
1013    def limit(
1014        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1015    ) -> Select:
1016        """
1017        Adds a LIMIT clause to this query.
1018
1019        Example:
1020            >>> select("1").union(select("1")).limit(1).sql()
1021            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
1022
1023        Args:
1024            expression: the SQL code string to parse.
1025                This can also be an integer.
1026                If a `Limit` instance is passed, it will be used as-is.
1027                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1028            dialect: the dialect used to parse the input expression.
1029            copy: if `False`, modify this expression instance in-place.
1030            opts: other options to use to parse the input expressions.
1031
1032        Returns:
1033            A limited Select expression.
1034        """
1035        return (
1036            select("*")
1037            .from_(self.subquery(alias="_l_0", copy=copy))
1038            .limit(expression, dialect=dialect, copy=False, **opts)
1039        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 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.

ctes: List[CTE]
1041    @property
1042    def ctes(self) -> t.List[CTE]:
1043        """Returns a list of all the CTEs attached to this query."""
1044        with_ = self.args.get("with")
1045        return with_.expressions if with_ else []

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

selects: List[Expression]
1047    @property
1048    def selects(self) -> t.List[Expression]:
1049        """Returns the query's projections."""
1050        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1052    @property
1053    def named_selects(self) -> t.List[str]:
1054        """Returns the output names of the query's projections."""
1055        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:
1057    def select(
1058        self: Q,
1059        *expressions: t.Optional[ExpOrStr],
1060        append: bool = True,
1061        dialect: DialectType = None,
1062        copy: bool = True,
1063        **opts,
1064    ) -> Q:
1065        """
1066        Append to or set the SELECT expressions.
1067
1068        Example:
1069            >>> Select().select("x", "y").sql()
1070            'SELECT x, y'
1071
1072        Args:
1073            *expressions: the SQL code strings to parse.
1074                If an `Expression` instance is passed, it will be used as-is.
1075            append: if `True`, add to any existing expressions.
1076                Otherwise, this resets the expressions.
1077            dialect: the dialect used to parse the input expressions.
1078            copy: if `False`, modify this expression instance in-place.
1079            opts: other options to use to parse the input expressions.
1080
1081        Returns:
1082            The modified Query expression.
1083        """
1084        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:
1086    def with_(
1087        self: Q,
1088        alias: ExpOrStr,
1089        as_: ExpOrStr,
1090        recursive: t.Optional[bool] = None,
1091        append: bool = True,
1092        dialect: DialectType = None,
1093        copy: bool = True,
1094        **opts,
1095    ) -> Q:
1096        """
1097        Append to or set the common table expressions.
1098
1099        Example:
1100            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1101            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1102
1103        Args:
1104            alias: the SQL code string to parse as the table name.
1105                If an `Expression` instance is passed, this is used as-is.
1106            as_: the SQL code string to parse as the table expression.
1107                If an `Expression` instance is passed, it will be used as-is.
1108            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1109            append: if `True`, add to any existing expressions.
1110                Otherwise, this resets the expressions.
1111            dialect: the dialect used to parse the input expression.
1112            copy: if `False`, modify this expression instance in-place.
1113            opts: other options to use to parse the input expressions.
1114
1115        Returns:
1116            The modified expression.
1117        """
1118        return _apply_cte_builder(
1119            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1120        )

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:
1122    def union(
1123        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1124    ) -> Union:
1125        """
1126        Builds a UNION expression.
1127
1128        Example:
1129            >>> import sqlglot
1130            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1131            'SELECT * FROM foo UNION SELECT * FROM bla'
1132
1133        Args:
1134            expression: the SQL code string.
1135                If an `Expression` instance is passed, it will be used as-is.
1136            distinct: set the DISTINCT flag if and only if this is true.
1137            dialect: the dialect used to parse the input expression.
1138            opts: other options to use to parse the input expressions.
1139
1140        Returns:
1141            The new Union expression.
1142        """
1143        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:
1145    def intersect(
1146        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1147    ) -> Intersect:
1148        """
1149        Builds an INTERSECT expression.
1150
1151        Example:
1152            >>> import sqlglot
1153            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1154            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1155
1156        Args:
1157            expression: the SQL code string.
1158                If an `Expression` instance is passed, it will be used as-is.
1159            distinct: set the DISTINCT flag if and only if this is true.
1160            dialect: the dialect used to parse the input expression.
1161            opts: other options to use to parse the input expressions.
1162
1163        Returns:
1164            The new Intersect expression.
1165        """
1166        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:
1168    def except_(
1169        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1170    ) -> Except:
1171        """
1172        Builds an EXCEPT expression.
1173
1174        Example:
1175            >>> import sqlglot
1176            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1177            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1178
1179        Args:
1180            expression: the SQL code string.
1181                If an `Expression` instance is passed, it will be used as-is.
1182            distinct: set the DISTINCT flag if and only if this is true.
1183            dialect: the dialect used to parse the input expression.
1184            opts: other options to use to parse the input expressions.
1185
1186        Returns:
1187            The new Except expression.
1188        """
1189        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):
1192class UDTF(DerivedTable):
1193    @property
1194    def selects(self) -> t.List[Expression]:
1195        alias = self.args.get("alias")
1196        return alias.columns if alias else []
selects: List[Expression]
1193    @property
1194    def selects(self) -> t.List[Expression]:
1195        alias = self.args.get("alias")
1196        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1199class Cache(Expression):
1200    arg_types = {
1201        "this": True,
1202        "lazy": False,
1203        "options": False,
1204        "expression": False,
1205    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1208class Uncache(Expression):
1209    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1212class Refresh(Expression):
1213    pass
key = 'refresh'
class DDL(Expression):
1216class DDL(Expression):
1217    @property
1218    def ctes(self) -> t.List[CTE]:
1219        """Returns a list of all the CTEs attached to this statement."""
1220        with_ = self.args.get("with")
1221        return with_.expressions if with_ else []
1222
1223    @property
1224    def selects(self) -> t.List[Expression]:
1225        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1226        return self.expression.selects if isinstance(self.expression, Query) else []
1227
1228    @property
1229    def named_selects(self) -> t.List[str]:
1230        """
1231        If this statement contains a query (e.g. a CTAS), this returns the output
1232        names of the query's projections.
1233        """
1234        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1217    @property
1218    def ctes(self) -> t.List[CTE]:
1219        """Returns a list of all the CTEs attached to this statement."""
1220        with_ = self.args.get("with")
1221        return with_.expressions if with_ else []

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

selects: List[Expression]
1223    @property
1224    def selects(self) -> t.List[Expression]:
1225        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1226        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]
1228    @property
1229    def named_selects(self) -> t.List[str]:
1230        """
1231        If this statement contains a query (e.g. a CTAS), this returns the output
1232        names of the query's projections.
1233        """
1234        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):
1237class DML(Expression):
1238    def returning(
1239        self,
1240        expression: ExpOrStr,
1241        dialect: DialectType = None,
1242        copy: bool = True,
1243        **opts,
1244    ) -> DML:
1245        """
1246        Set the RETURNING expression. Not supported by all dialects.
1247
1248        Example:
1249            >>> delete("tbl").returning("*", dialect="postgres").sql()
1250            'DELETE FROM tbl RETURNING *'
1251
1252        Args:
1253            expression: the SQL code strings to parse.
1254                If an `Expression` instance is passed, it will be used as-is.
1255            dialect: the dialect used to parse the input expressions.
1256            copy: if `False`, modify this expression instance in-place.
1257            opts: other options to use to parse the input expressions.
1258
1259        Returns:
1260            Delete: the modified expression.
1261        """
1262        return _apply_builder(
1263            expression=expression,
1264            instance=self,
1265            arg="returning",
1266            prefix="RETURNING",
1267            dialect=dialect,
1268            copy=copy,
1269            into=Returning,
1270            **opts,
1271        )
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:
1238    def returning(
1239        self,
1240        expression: ExpOrStr,
1241        dialect: DialectType = None,
1242        copy: bool = True,
1243        **opts,
1244    ) -> DML:
1245        """
1246        Set the RETURNING expression. Not supported by all dialects.
1247
1248        Example:
1249            >>> delete("tbl").returning("*", dialect="postgres").sql()
1250            'DELETE FROM tbl RETURNING *'
1251
1252        Args:
1253            expression: the SQL code strings to parse.
1254                If an `Expression` instance is passed, it will be used as-is.
1255            dialect: the dialect used to parse the input expressions.
1256            copy: if `False`, modify this expression instance in-place.
1257            opts: other options to use to parse the input expressions.
1258
1259        Returns:
1260            Delete: the modified expression.
1261        """
1262        return _apply_builder(
1263            expression=expression,
1264            instance=self,
1265            arg="returning",
1266            prefix="RETURNING",
1267            dialect=dialect,
1268            copy=copy,
1269            into=Returning,
1270            **opts,
1271        )

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):
1274class Create(DDL):
1275    arg_types = {
1276        "with": False,
1277        "this": True,
1278        "kind": True,
1279        "expression": False,
1280        "exists": False,
1281        "properties": False,
1282        "replace": False,
1283        "unique": False,
1284        "indexes": False,
1285        "no_schema_binding": False,
1286        "begin": False,
1287        "end": False,
1288        "clone": False,
1289    }
1290
1291    @property
1292    def kind(self) -> t.Optional[str]:
1293        kind = self.args.get("kind")
1294        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]
1291    @property
1292    def kind(self) -> t.Optional[str]:
1293        kind = self.args.get("kind")
1294        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1297class SequenceProperties(Expression):
1298    arg_types = {
1299        "increment": False,
1300        "minvalue": False,
1301        "maxvalue": False,
1302        "cache": False,
1303        "start": False,
1304        "owned": False,
1305        "options": False,
1306    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1309class TruncateTable(Expression):
1310    arg_types = {
1311        "expressions": True,
1312        "is_database": False,
1313        "exists": False,
1314        "only": False,
1315        "cluster": False,
1316        "identity": False,
1317        "option": False,
1318        "partition": False,
1319    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1325class Clone(Expression):
1326    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1329class Describe(Expression):
1330    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'extended': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1333class Kill(Expression):
1334    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1337class Pragma(Expression):
1338    pass
key = 'pragma'
class Set(Expression):
1341class Set(Expression):
1342    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1345class Heredoc(Expression):
1346    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1349class SetItem(Expression):
1350    arg_types = {
1351        "this": False,
1352        "expressions": False,
1353        "kind": False,
1354        "collate": False,  # MySQL SET NAMES statement
1355        "global": False,
1356    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1359class Show(Expression):
1360    arg_types = {
1361        "this": True,
1362        "history": False,
1363        "terse": False,
1364        "target": False,
1365        "offset": False,
1366        "starts_with": False,
1367        "limit": False,
1368        "from": False,
1369        "like": False,
1370        "where": False,
1371        "db": False,
1372        "scope": False,
1373        "scope_kind": False,
1374        "full": False,
1375        "mutex": False,
1376        "query": False,
1377        "channel": False,
1378        "global": False,
1379        "log": False,
1380        "position": False,
1381        "types": False,
1382    }
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):
1385class UserDefinedFunction(Expression):
1386    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1389class CharacterSet(Expression):
1390    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1393class With(Expression):
1394    arg_types = {"expressions": True, "recursive": False}
1395
1396    @property
1397    def recursive(self) -> bool:
1398        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1396    @property
1397    def recursive(self) -> bool:
1398        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1401class WithinGroup(Expression):
1402    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1407class CTE(DerivedTable):
1408    arg_types = {
1409        "this": True,
1410        "alias": True,
1411        "scalar": False,
1412        "materialized": False,
1413    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class TableAlias(Expression):
1416class TableAlias(Expression):
1417    arg_types = {"this": False, "columns": False}
1418
1419    @property
1420    def columns(self):
1421        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1419    @property
1420    def columns(self):
1421        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1424class BitString(Condition):
1425    pass
key = 'bitstring'
class HexString(Condition):
1428class HexString(Condition):
1429    pass
key = 'hexstring'
class ByteString(Condition):
1432class ByteString(Condition):
1433    pass
key = 'bytestring'
class RawString(Condition):
1436class RawString(Condition):
1437    pass
key = 'rawstring'
class UnicodeString(Condition):
1440class UnicodeString(Condition):
1441    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1444class Column(Condition):
1445    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1446
1447    @property
1448    def table(self) -> str:
1449        return self.text("table")
1450
1451    @property
1452    def db(self) -> str:
1453        return self.text("db")
1454
1455    @property
1456    def catalog(self) -> str:
1457        return self.text("catalog")
1458
1459    @property
1460    def output_name(self) -> str:
1461        return self.name
1462
1463    @property
1464    def parts(self) -> t.List[Identifier]:
1465        """Return the parts of a column in order catalog, db, table, name."""
1466        return [
1467            t.cast(Identifier, self.args[part])
1468            for part in ("catalog", "db", "table", "this")
1469            if self.args.get(part)
1470        ]
1471
1472    def to_dot(self) -> Dot | Identifier:
1473        """Converts the column into a dot expression."""
1474        parts = self.parts
1475        parent = self.parent
1476
1477        while parent:
1478            if isinstance(parent, Dot):
1479                parts.append(parent.expression)
1480            parent = parent.parent
1481
1482        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
1447    @property
1448    def table(self) -> str:
1449        return self.text("table")
db: str
1451    @property
1452    def db(self) -> str:
1453        return self.text("db")
catalog: str
1455    @property
1456    def catalog(self) -> str:
1457        return self.text("catalog")
output_name: str
1459    @property
1460    def output_name(self) -> str:
1461        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]
1463    @property
1464    def parts(self) -> t.List[Identifier]:
1465        """Return the parts of a column in order catalog, db, table, name."""
1466        return [
1467            t.cast(Identifier, self.args[part])
1468            for part in ("catalog", "db", "table", "this")
1469            if self.args.get(part)
1470        ]

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

def to_dot(self) -> Dot | Identifier:
1472    def to_dot(self) -> Dot | Identifier:
1473        """Converts the column into a dot expression."""
1474        parts = self.parts
1475        parent = self.parent
1476
1477        while parent:
1478            if isinstance(parent, Dot):
1479                parts.append(parent.expression)
1480            parent = parent.parent
1481
1482        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1485class ColumnPosition(Expression):
1486    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1489class ColumnDef(Expression):
1490    arg_types = {
1491        "this": True,
1492        "kind": False,
1493        "constraints": False,
1494        "exists": False,
1495        "position": False,
1496    }
1497
1498    @property
1499    def constraints(self) -> t.List[ColumnConstraint]:
1500        return self.args.get("constraints") or []
1501
1502    @property
1503    def kind(self) -> t.Optional[DataType]:
1504        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1498    @property
1499    def constraints(self) -> t.List[ColumnConstraint]:
1500        return self.args.get("constraints") or []
kind: Optional[DataType]
1502    @property
1503    def kind(self) -> t.Optional[DataType]:
1504        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1507class AlterColumn(Expression):
1508    arg_types = {
1509        "this": True,
1510        "dtype": False,
1511        "collate": False,
1512        "using": False,
1513        "default": False,
1514        "drop": False,
1515        "comment": False,
1516    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1519class RenameColumn(Expression):
1520    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1523class RenameTable(Expression):
1524    pass
key = 'renametable'
class SwapTable(Expression):
1527class SwapTable(Expression):
1528    pass
key = 'swaptable'
class Comment(Expression):
1531class Comment(Expression):
1532    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False}
key = 'comment'
class Comprehension(Expression):
1535class Comprehension(Expression):
1536    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):
1540class MergeTreeTTLAction(Expression):
1541    arg_types = {
1542        "this": True,
1543        "delete": False,
1544        "recompress": False,
1545        "to_disk": False,
1546        "to_volume": False,
1547    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1551class MergeTreeTTL(Expression):
1552    arg_types = {
1553        "expressions": True,
1554        "where": False,
1555        "group": False,
1556        "aggregates": False,
1557    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1561class IndexConstraintOption(Expression):
1562    arg_types = {
1563        "key_block_size": False,
1564        "using": False,
1565        "parser": False,
1566        "comment": False,
1567        "visible": False,
1568        "engine_attr": False,
1569        "secondary_engine_attr": False,
1570    }
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):
1573class ColumnConstraint(Expression):
1574    arg_types = {"this": False, "kind": True}
1575
1576    @property
1577    def kind(self) -> ColumnConstraintKind:
1578        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1576    @property
1577    def kind(self) -> ColumnConstraintKind:
1578        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1581class ColumnConstraintKind(Expression):
1582    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1585class AutoIncrementColumnConstraint(ColumnConstraintKind):
1586    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1589class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1590    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1593class CaseSpecificColumnConstraint(ColumnConstraintKind):
1594    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1597class CharacterSetColumnConstraint(ColumnConstraintKind):
1598    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1601class CheckColumnConstraint(ColumnConstraintKind):
1602    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1605class ClusteredColumnConstraint(ColumnConstraintKind):
1606    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1609class CollateColumnConstraint(ColumnConstraintKind):
1610    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1613class CommentColumnConstraint(ColumnConstraintKind):
1614    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1617class CompressColumnConstraint(ColumnConstraintKind):
1618    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1621class DateFormatColumnConstraint(ColumnConstraintKind):
1622    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1625class DefaultColumnConstraint(ColumnConstraintKind):
1626    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1629class EncodeColumnConstraint(ColumnConstraintKind):
1630    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1634class ExcludeColumnConstraint(ColumnConstraintKind):
1635    pass
key = 'excludecolumnconstraint'
class WithOperator(Expression):
1638class WithOperator(Expression):
1639    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1642class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1643    # this: True -> ALWAYS, this: False -> BY DEFAULT
1644    arg_types = {
1645        "this": False,
1646        "expression": False,
1647        "on_null": False,
1648        "start": False,
1649        "increment": False,
1650        "minvalue": False,
1651        "maxvalue": False,
1652        "cycle": False,
1653    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1656class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1657    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1661class IndexColumnConstraint(ColumnConstraintKind):
1662    arg_types = {
1663        "this": False,
1664        "schema": True,
1665        "kind": False,
1666        "index_type": False,
1667        "options": False,
1668    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1671class InlineLengthColumnConstraint(ColumnConstraintKind):
1672    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1675class NonClusteredColumnConstraint(ColumnConstraintKind):
1676    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1679class NotForReplicationColumnConstraint(ColumnConstraintKind):
1680    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1683class NotNullColumnConstraint(ColumnConstraintKind):
1684    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1688class OnUpdateColumnConstraint(ColumnConstraintKind):
1689    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1693class TransformColumnConstraint(ColumnConstraintKind):
1694    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1697class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1698    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1701class TitleColumnConstraint(ColumnConstraintKind):
1702    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1705class UniqueColumnConstraint(ColumnConstraintKind):
1706    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):
1709class UppercaseColumnConstraint(ColumnConstraintKind):
1710    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1713class PathColumnConstraint(ColumnConstraintKind):
1714    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1719class ComputedColumnConstraint(ColumnConstraintKind):
1720    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1723class Constraint(Expression):
1724    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1727class Delete(DML):
1728    arg_types = {
1729        "with": False,
1730        "this": False,
1731        "using": False,
1732        "where": False,
1733        "returning": False,
1734        "limit": False,
1735        "tables": False,  # Multiple-Table Syntax (MySQL)
1736    }
1737
1738    def delete(
1739        self,
1740        table: ExpOrStr,
1741        dialect: DialectType = None,
1742        copy: bool = True,
1743        **opts,
1744    ) -> Delete:
1745        """
1746        Create a DELETE expression or replace the table on an existing DELETE expression.
1747
1748        Example:
1749            >>> delete("tbl").sql()
1750            'DELETE FROM tbl'
1751
1752        Args:
1753            table: the table from which to delete.
1754            dialect: the dialect used to parse the input expression.
1755            copy: if `False`, modify this expression instance in-place.
1756            opts: other options to use to parse the input expressions.
1757
1758        Returns:
1759            Delete: the modified expression.
1760        """
1761        return _apply_builder(
1762            expression=table,
1763            instance=self,
1764            arg="this",
1765            dialect=dialect,
1766            into=Table,
1767            copy=copy,
1768            **opts,
1769        )
1770
1771    def where(
1772        self,
1773        *expressions: t.Optional[ExpOrStr],
1774        append: bool = True,
1775        dialect: DialectType = None,
1776        copy: bool = True,
1777        **opts,
1778    ) -> Delete:
1779        """
1780        Append to or set the WHERE expressions.
1781
1782        Example:
1783            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1784            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1785
1786        Args:
1787            *expressions: the SQL code strings to parse.
1788                If an `Expression` instance is passed, it will be used as-is.
1789                Multiple expressions are combined with an AND operator.
1790            append: if `True`, AND the new expressions to any existing expression.
1791                Otherwise, this resets the expression.
1792            dialect: the dialect used to parse the input expressions.
1793            copy: if `False`, modify this expression instance in-place.
1794            opts: other options to use to parse the input expressions.
1795
1796        Returns:
1797            Delete: the modified expression.
1798        """
1799        return _apply_conjunction_builder(
1800            *expressions,
1801            instance=self,
1802            arg="where",
1803            append=append,
1804            into=Where,
1805            dialect=dialect,
1806            copy=copy,
1807            **opts,
1808        )
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:
1738    def delete(
1739        self,
1740        table: ExpOrStr,
1741        dialect: DialectType = None,
1742        copy: bool = True,
1743        **opts,
1744    ) -> Delete:
1745        """
1746        Create a DELETE expression or replace the table on an existing DELETE expression.
1747
1748        Example:
1749            >>> delete("tbl").sql()
1750            'DELETE FROM tbl'
1751
1752        Args:
1753            table: the table from which to delete.
1754            dialect: the dialect used to parse the input expression.
1755            copy: if `False`, modify this expression instance in-place.
1756            opts: other options to use to parse the input expressions.
1757
1758        Returns:
1759            Delete: the modified expression.
1760        """
1761        return _apply_builder(
1762            expression=table,
1763            instance=self,
1764            arg="this",
1765            dialect=dialect,
1766            into=Table,
1767            copy=copy,
1768            **opts,
1769        )

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:
1771    def where(
1772        self,
1773        *expressions: t.Optional[ExpOrStr],
1774        append: bool = True,
1775        dialect: DialectType = None,
1776        copy: bool = True,
1777        **opts,
1778    ) -> Delete:
1779        """
1780        Append to or set the WHERE expressions.
1781
1782        Example:
1783            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1784            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1785
1786        Args:
1787            *expressions: the SQL code strings to parse.
1788                If an `Expression` instance is passed, it will be used as-is.
1789                Multiple expressions are combined with an AND operator.
1790            append: if `True`, AND the new expressions to any existing expression.
1791                Otherwise, this resets the expression.
1792            dialect: the dialect used to parse the input expressions.
1793            copy: if `False`, modify this expression instance in-place.
1794            opts: other options to use to parse the input expressions.
1795
1796        Returns:
1797            Delete: the modified expression.
1798        """
1799        return _apply_conjunction_builder(
1800            *expressions,
1801            instance=self,
1802            arg="where",
1803            append=append,
1804            into=Where,
1805            dialect=dialect,
1806            copy=copy,
1807            **opts,
1808        )

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):
1811class Drop(Expression):
1812    arg_types = {
1813        "this": False,
1814        "kind": False,
1815        "expressions": False,
1816        "exists": False,
1817        "temporary": False,
1818        "materialized": False,
1819        "cascade": False,
1820        "constraints": False,
1821        "purge": False,
1822    }
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):
1825class Filter(Expression):
1826    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1829class Check(Expression):
1830    pass
key = 'check'
class Connect(Expression):
1834class Connect(Expression):
1835    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1838class Prior(Expression):
1839    pass
key = 'prior'
class Directory(Expression):
1842class Directory(Expression):
1843    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1844    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1847class ForeignKey(Expression):
1848    arg_types = {
1849        "expressions": True,
1850        "reference": False,
1851        "delete": False,
1852        "update": False,
1853    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1856class ColumnPrefix(Expression):
1857    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1860class PrimaryKey(Expression):
1861    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1866class Into(Expression):
1867    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1870class From(Expression):
1871    @property
1872    def name(self) -> str:
1873        return self.this.name
1874
1875    @property
1876    def alias_or_name(self) -> str:
1877        return self.this.alias_or_name
name: str
1871    @property
1872    def name(self) -> str:
1873        return self.this.name
alias_or_name: str
1875    @property
1876    def alias_or_name(self) -> str:
1877        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1880class Having(Expression):
1881    pass
key = 'having'
class Hint(Expression):
1884class Hint(Expression):
1885    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1888class JoinHint(Expression):
1889    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1892class Identifier(Expression):
1893    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1894
1895    @property
1896    def quoted(self) -> bool:
1897        return bool(self.args.get("quoted"))
1898
1899    @property
1900    def hashable_args(self) -> t.Any:
1901        return (self.this, self.quoted)
1902
1903    @property
1904    def output_name(self) -> str:
1905        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1895    @property
1896    def quoted(self) -> bool:
1897        return bool(self.args.get("quoted"))
hashable_args: Any
1899    @property
1900    def hashable_args(self) -> t.Any:
1901        return (self.this, self.quoted)
output_name: str
1903    @property
1904    def output_name(self) -> str:
1905        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):
1909class Opclass(Expression):
1910    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1913class Index(Expression):
1914    arg_types = {
1915        "this": False,
1916        "table": False,
1917        "unique": False,
1918        "primary": False,
1919        "amp": False,  # teradata
1920        "params": False,
1921    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
1924class IndexParameters(Expression):
1925    arg_types = {
1926        "using": False,
1927        "include": False,
1928        "columns": False,
1929        "with_storage": False,
1930        "partition_by": False,
1931        "tablespace": False,
1932        "where": False,
1933    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
1936class Insert(DDL, DML):
1937    arg_types = {
1938        "hint": False,
1939        "with": False,
1940        "is_function": False,
1941        "this": True,
1942        "expression": False,
1943        "conflict": False,
1944        "returning": False,
1945        "overwrite": False,
1946        "exists": False,
1947        "partition": False,
1948        "alternative": False,
1949        "where": False,
1950        "ignore": False,
1951        "by_name": False,
1952    }
1953
1954    def with_(
1955        self,
1956        alias: ExpOrStr,
1957        as_: ExpOrStr,
1958        recursive: t.Optional[bool] = None,
1959        append: bool = True,
1960        dialect: DialectType = None,
1961        copy: bool = True,
1962        **opts,
1963    ) -> Insert:
1964        """
1965        Append to or set the common table expressions.
1966
1967        Example:
1968            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1969            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1970
1971        Args:
1972            alias: the SQL code string to parse as the table name.
1973                If an `Expression` instance is passed, this is used as-is.
1974            as_: the SQL code string to parse as the table expression.
1975                If an `Expression` instance is passed, it will be used as-is.
1976            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1977            append: if `True`, add to any existing expressions.
1978                Otherwise, this resets the expressions.
1979            dialect: the dialect used to parse the input expression.
1980            copy: if `False`, modify this expression instance in-place.
1981            opts: other options to use to parse the input expressions.
1982
1983        Returns:
1984            The modified expression.
1985        """
1986        return _apply_cte_builder(
1987            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1988        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': 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:
1954    def with_(
1955        self,
1956        alias: ExpOrStr,
1957        as_: ExpOrStr,
1958        recursive: t.Optional[bool] = None,
1959        append: bool = True,
1960        dialect: DialectType = None,
1961        copy: bool = True,
1962        **opts,
1963    ) -> Insert:
1964        """
1965        Append to or set the common table expressions.
1966
1967        Example:
1968            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1969            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1970
1971        Args:
1972            alias: the SQL code string to parse as the table name.
1973                If an `Expression` instance is passed, this is used as-is.
1974            as_: the SQL code string to parse as the table expression.
1975                If an `Expression` instance is passed, it will be used as-is.
1976            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1977            append: if `True`, add to any existing expressions.
1978                Otherwise, this resets the expressions.
1979            dialect: the dialect used to parse the input expression.
1980            copy: if `False`, modify this expression instance in-place.
1981            opts: other options to use to parse the input expressions.
1982
1983        Returns:
1984            The modified expression.
1985        """
1986        return _apply_cte_builder(
1987            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1988        )

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):
1991class OnConflict(Expression):
1992    arg_types = {
1993        "duplicate": False,
1994        "expressions": False,
1995        "action": False,
1996        "conflict_keys": False,
1997        "constraint": False,
1998    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2001class Returning(Expression):
2002    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2006class Introducer(Expression):
2007    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2011class National(Expression):
2012    pass
key = 'national'
class LoadData(Expression):
2015class LoadData(Expression):
2016    arg_types = {
2017        "this": True,
2018        "local": False,
2019        "overwrite": False,
2020        "inpath": True,
2021        "partition": False,
2022        "input_format": False,
2023        "serde": False,
2024    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2027class Partition(Expression):
2028    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2031class PartitionRange(Expression):
2032    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
2035class Fetch(Expression):
2036    arg_types = {
2037        "direction": False,
2038        "count": False,
2039        "percent": False,
2040        "with_ties": False,
2041    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2044class Group(Expression):
2045    arg_types = {
2046        "expressions": False,
2047        "grouping_sets": False,
2048        "cube": False,
2049        "rollup": False,
2050        "totals": False,
2051        "all": False,
2052    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2055class Lambda(Expression):
2056    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2059class Limit(Expression):
2060    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):
2063class Literal(Condition):
2064    arg_types = {"this": True, "is_string": True}
2065
2066    @property
2067    def hashable_args(self) -> t.Any:
2068        return (self.this, self.args.get("is_string"))
2069
2070    @classmethod
2071    def number(cls, number) -> Literal:
2072        return cls(this=str(number), is_string=False)
2073
2074    @classmethod
2075    def string(cls, string) -> Literal:
2076        return cls(this=str(string), is_string=True)
2077
2078    @property
2079    def output_name(self) -> str:
2080        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2066    @property
2067    def hashable_args(self) -> t.Any:
2068        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2070    @classmethod
2071    def number(cls, number) -> Literal:
2072        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2074    @classmethod
2075    def string(cls, string) -> Literal:
2076        return cls(this=str(string), is_string=True)
output_name: str
2078    @property
2079    def output_name(self) -> str:
2080        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):
2083class Join(Expression):
2084    arg_types = {
2085        "this": True,
2086        "on": False,
2087        "side": False,
2088        "kind": False,
2089        "using": False,
2090        "method": False,
2091        "global": False,
2092        "hint": False,
2093    }
2094
2095    @property
2096    def method(self) -> str:
2097        return self.text("method").upper()
2098
2099    @property
2100    def kind(self) -> str:
2101        return self.text("kind").upper()
2102
2103    @property
2104    def side(self) -> str:
2105        return self.text("side").upper()
2106
2107    @property
2108    def hint(self) -> str:
2109        return self.text("hint").upper()
2110
2111    @property
2112    def alias_or_name(self) -> str:
2113        return self.this.alias_or_name
2114
2115    def on(
2116        self,
2117        *expressions: t.Optional[ExpOrStr],
2118        append: bool = True,
2119        dialect: DialectType = None,
2120        copy: bool = True,
2121        **opts,
2122    ) -> Join:
2123        """
2124        Append to or set the ON expressions.
2125
2126        Example:
2127            >>> import sqlglot
2128            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2129            'JOIN x ON y = 1'
2130
2131        Args:
2132            *expressions: the SQL code strings to parse.
2133                If an `Expression` instance is passed, it will be used as-is.
2134                Multiple expressions are combined with an AND operator.
2135            append: if `True`, AND the new expressions to any existing expression.
2136                Otherwise, this resets the expression.
2137            dialect: the dialect used to parse the input expressions.
2138            copy: if `False`, modify this expression instance in-place.
2139            opts: other options to use to parse the input expressions.
2140
2141        Returns:
2142            The modified Join expression.
2143        """
2144        join = _apply_conjunction_builder(
2145            *expressions,
2146            instance=self,
2147            arg="on",
2148            append=append,
2149            dialect=dialect,
2150            copy=copy,
2151            **opts,
2152        )
2153
2154        if join.kind == "CROSS":
2155            join.set("kind", None)
2156
2157        return join
2158
2159    def using(
2160        self,
2161        *expressions: t.Optional[ExpOrStr],
2162        append: bool = True,
2163        dialect: DialectType = None,
2164        copy: bool = True,
2165        **opts,
2166    ) -> Join:
2167        """
2168        Append to or set the USING expressions.
2169
2170        Example:
2171            >>> import sqlglot
2172            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2173            'JOIN x USING (foo, bla)'
2174
2175        Args:
2176            *expressions: the SQL code strings to parse.
2177                If an `Expression` instance is passed, it will be used as-is.
2178            append: if `True`, concatenate the new expressions to the existing "using" list.
2179                Otherwise, this resets the expression.
2180            dialect: the dialect used to parse the input expressions.
2181            copy: if `False`, modify this expression instance in-place.
2182            opts: other options to use to parse the input expressions.
2183
2184        Returns:
2185            The modified Join expression.
2186        """
2187        join = _apply_list_builder(
2188            *expressions,
2189            instance=self,
2190            arg="using",
2191            append=append,
2192            dialect=dialect,
2193            copy=copy,
2194            **opts,
2195        )
2196
2197        if join.kind == "CROSS":
2198            join.set("kind", None)
2199
2200        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
2095    @property
2096    def method(self) -> str:
2097        return self.text("method").upper()
kind: str
2099    @property
2100    def kind(self) -> str:
2101        return self.text("kind").upper()
side: str
2103    @property
2104    def side(self) -> str:
2105        return self.text("side").upper()
hint: str
2107    @property
2108    def hint(self) -> str:
2109        return self.text("hint").upper()
alias_or_name: str
2111    @property
2112    def alias_or_name(self) -> str:
2113        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:
2115    def on(
2116        self,
2117        *expressions: t.Optional[ExpOrStr],
2118        append: bool = True,
2119        dialect: DialectType = None,
2120        copy: bool = True,
2121        **opts,
2122    ) -> Join:
2123        """
2124        Append to or set the ON expressions.
2125
2126        Example:
2127            >>> import sqlglot
2128            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2129            'JOIN x ON y = 1'
2130
2131        Args:
2132            *expressions: the SQL code strings to parse.
2133                If an `Expression` instance is passed, it will be used as-is.
2134                Multiple expressions are combined with an AND operator.
2135            append: if `True`, AND the new expressions to any existing expression.
2136                Otherwise, this resets the expression.
2137            dialect: the dialect used to parse the input expressions.
2138            copy: if `False`, modify this expression instance in-place.
2139            opts: other options to use to parse the input expressions.
2140
2141        Returns:
2142            The modified Join expression.
2143        """
2144        join = _apply_conjunction_builder(
2145            *expressions,
2146            instance=self,
2147            arg="on",
2148            append=append,
2149            dialect=dialect,
2150            copy=copy,
2151            **opts,
2152        )
2153
2154        if join.kind == "CROSS":
2155            join.set("kind", None)
2156
2157        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:
2159    def using(
2160        self,
2161        *expressions: t.Optional[ExpOrStr],
2162        append: bool = True,
2163        dialect: DialectType = None,
2164        copy: bool = True,
2165        **opts,
2166    ) -> Join:
2167        """
2168        Append to or set the USING expressions.
2169
2170        Example:
2171            >>> import sqlglot
2172            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2173            'JOIN x USING (foo, bla)'
2174
2175        Args:
2176            *expressions: the SQL code strings to parse.
2177                If an `Expression` instance is passed, it will be used as-is.
2178            append: if `True`, concatenate the new expressions to the existing "using" list.
2179                Otherwise, this resets the expression.
2180            dialect: the dialect used to parse the input expressions.
2181            copy: if `False`, modify this expression instance in-place.
2182            opts: other options to use to parse the input expressions.
2183
2184        Returns:
2185            The modified Join expression.
2186        """
2187        join = _apply_list_builder(
2188            *expressions,
2189            instance=self,
2190            arg="using",
2191            append=append,
2192            dialect=dialect,
2193            copy=copy,
2194            **opts,
2195        )
2196
2197        if join.kind == "CROSS":
2198            join.set("kind", None)
2199
2200        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):
2203class Lateral(UDTF):
2204    arg_types = {
2205        "this": True,
2206        "view": False,
2207        "outer": False,
2208        "alias": False,
2209        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2210    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
2213class MatchRecognize(Expression):
2214    arg_types = {
2215        "partition_by": False,
2216        "order": False,
2217        "measures": False,
2218        "rows": False,
2219        "after": False,
2220        "pattern": False,
2221        "define": False,
2222        "alias": False,
2223    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2228class Final(Expression):
2229    pass
key = 'final'
class Offset(Expression):
2232class Offset(Expression):
2233    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2236class Order(Expression):
2237    arg_types = {
2238        "this": False,
2239        "expressions": True,
2240        "interpolate": False,
2241        "siblings": False,
2242    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2246class WithFill(Expression):
2247    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2252class Cluster(Order):
2253    pass
key = 'cluster'
class Distribute(Order):
2256class Distribute(Order):
2257    pass
key = 'distribute'
class Sort(Order):
2260class Sort(Order):
2261    pass
key = 'sort'
class Ordered(Expression):
2264class Ordered(Expression):
2265    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):
2268class Property(Expression):
2269    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2272class AlgorithmProperty(Property):
2273    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2276class AutoIncrementProperty(Property):
2277    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2281class AutoRefreshProperty(Property):
2282    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2285class BackupProperty(Property):
2286    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2289class BlockCompressionProperty(Property):
2290    arg_types = {
2291        "autotemp": False,
2292        "always": False,
2293        "default": False,
2294        "manual": False,
2295        "never": False,
2296    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2299class CharacterSetProperty(Property):
2300    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2303class ChecksumProperty(Property):
2304    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2307class CollateProperty(Property):
2308    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2311class CopyGrantsProperty(Property):
2312    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2315class DataBlocksizeProperty(Property):
2316    arg_types = {
2317        "size": False,
2318        "units": False,
2319        "minimum": False,
2320        "maximum": False,
2321        "default": False,
2322    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2325class DefinerProperty(Property):
2326    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2329class DistKeyProperty(Property):
2330    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2333class DistStyleProperty(Property):
2334    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2337class EngineProperty(Property):
2338    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2341class HeapProperty(Property):
2342    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2345class ToTableProperty(Property):
2346    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2349class ExecuteAsProperty(Property):
2350    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2353class ExternalProperty(Property):
2354    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2357class FallbackProperty(Property):
2358    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2361class FileFormatProperty(Property):
2362    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2365class FreespaceProperty(Property):
2366    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2369class GlobalProperty(Property):
2370    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2373class IcebergProperty(Property):
2374    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2377class InheritsProperty(Property):
2378    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2381class InputModelProperty(Property):
2382    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2385class OutputModelProperty(Property):
2386    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2389class IsolatedLoadingProperty(Property):
2390    arg_types = {
2391        "no": False,
2392        "concurrent": False,
2393        "for_all": False,
2394        "for_insert": False,
2395        "for_none": False,
2396    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2399class JournalProperty(Property):
2400    arg_types = {
2401        "no": False,
2402        "dual": False,
2403        "before": False,
2404        "local": False,
2405        "after": False,
2406    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2409class LanguageProperty(Property):
2410    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2414class ClusteredByProperty(Property):
2415    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2418class DictProperty(Property):
2419    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2422class DictSubProperty(Property):
2423    pass
key = 'dictsubproperty'
class DictRange(Property):
2426class DictRange(Property):
2427    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2432class OnCluster(Property):
2433    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2436class LikeProperty(Property):
2437    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2440class LocationProperty(Property):
2441    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2444class LockProperty(Property):
2445    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2448class LockingProperty(Property):
2449    arg_types = {
2450        "this": False,
2451        "kind": True,
2452        "for_or_in": False,
2453        "lock_type": True,
2454        "override": False,
2455    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2458class LogProperty(Property):
2459    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2462class MaterializedProperty(Property):
2463    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2466class MergeBlockRatioProperty(Property):
2467    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):
2470class NoPrimaryIndexProperty(Property):
2471    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2474class OnProperty(Property):
2475    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2478class OnCommitProperty(Property):
2479    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2482class PartitionedByProperty(Property):
2483    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2487class PartitionBoundSpec(Expression):
2488    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2489    arg_types = {
2490        "this": False,
2491        "expression": False,
2492        "from_expressions": False,
2493        "to_expressions": False,
2494    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2497class PartitionedOfProperty(Property):
2498    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2499    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2502class RemoteWithConnectionModelProperty(Property):
2503    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2506class ReturnsProperty(Property):
2507    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2510class RowFormatProperty(Property):
2511    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2514class RowFormatDelimitedProperty(Property):
2515    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2516    arg_types = {
2517        "fields": False,
2518        "escaped": False,
2519        "collection_items": False,
2520        "map_keys": False,
2521        "lines": False,
2522        "null": False,
2523        "serde": False,
2524    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2527class RowFormatSerdeProperty(Property):
2528    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2532class QueryTransform(Expression):
2533    arg_types = {
2534        "expressions": True,
2535        "command_script": True,
2536        "schema": False,
2537        "row_format_before": False,
2538        "record_writer": False,
2539        "row_format_after": False,
2540        "record_reader": False,
2541    }
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):
2544class SampleProperty(Property):
2545    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2548class SchemaCommentProperty(Property):
2549    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2552class SerdeProperties(Property):
2553    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2556class SetProperty(Property):
2557    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2560class SharingProperty(Property):
2561    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2564class SetConfigProperty(Property):
2565    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2568class SettingsProperty(Property):
2569    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2572class SortKeyProperty(Property):
2573    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2576class SqlReadWriteProperty(Property):
2577    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2580class SqlSecurityProperty(Property):
2581    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2584class StabilityProperty(Property):
2585    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2588class TemporaryProperty(Property):
2589    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2592class TransformModelProperty(Property):
2593    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2596class TransientProperty(Property):
2597    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2600class UnloggedProperty(Property):
2601    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class VolatileProperty(Property):
2604class VolatileProperty(Property):
2605    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2608class WithDataProperty(Property):
2609    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2612class WithJournalTableProperty(Property):
2613    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2616class WithSystemVersioningProperty(Property):
2617    # this -> history table name, expression -> data consistency check
2618    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2621class Properties(Expression):
2622    arg_types = {"expressions": True}
2623
2624    NAME_TO_PROPERTY = {
2625        "ALGORITHM": AlgorithmProperty,
2626        "AUTO_INCREMENT": AutoIncrementProperty,
2627        "CHARACTER SET": CharacterSetProperty,
2628        "CLUSTERED_BY": ClusteredByProperty,
2629        "COLLATE": CollateProperty,
2630        "COMMENT": SchemaCommentProperty,
2631        "DEFINER": DefinerProperty,
2632        "DISTKEY": DistKeyProperty,
2633        "DISTSTYLE": DistStyleProperty,
2634        "ENGINE": EngineProperty,
2635        "EXECUTE AS": ExecuteAsProperty,
2636        "FORMAT": FileFormatProperty,
2637        "LANGUAGE": LanguageProperty,
2638        "LOCATION": LocationProperty,
2639        "LOCK": LockProperty,
2640        "PARTITIONED_BY": PartitionedByProperty,
2641        "RETURNS": ReturnsProperty,
2642        "ROW_FORMAT": RowFormatProperty,
2643        "SORTKEY": SortKeyProperty,
2644    }
2645
2646    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2647
2648    # CREATE property locations
2649    # Form: schema specified
2650    #   create [POST_CREATE]
2651    #     table a [POST_NAME]
2652    #     (b int) [POST_SCHEMA]
2653    #     with ([POST_WITH])
2654    #     index (b) [POST_INDEX]
2655    #
2656    # Form: alias selection
2657    #   create [POST_CREATE]
2658    #     table a [POST_NAME]
2659    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2660    #     index (c) [POST_INDEX]
2661    class Location(AutoName):
2662        POST_CREATE = auto()
2663        POST_NAME = auto()
2664        POST_SCHEMA = auto()
2665        POST_WITH = auto()
2666        POST_ALIAS = auto()
2667        POST_EXPRESSION = auto()
2668        POST_INDEX = auto()
2669        UNSUPPORTED = auto()
2670
2671    @classmethod
2672    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2673        expressions = []
2674        for key, value in properties_dict.items():
2675            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2676            if property_cls:
2677                expressions.append(property_cls(this=convert(value)))
2678            else:
2679                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2680
2681        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:
2671    @classmethod
2672    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2673        expressions = []
2674        for key, value in properties_dict.items():
2675            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2676            if property_cls:
2677                expressions.append(property_cls(this=convert(value)))
2678            else:
2679                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2680
2681        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2661    class Location(AutoName):
2662        POST_CREATE = auto()
2663        POST_NAME = auto()
2664        POST_SCHEMA = auto()
2665        POST_WITH = auto()
2666        POST_ALIAS = auto()
2667        POST_EXPRESSION = auto()
2668        POST_INDEX = auto()
2669        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):
2684class Qualify(Expression):
2685    pass
key = 'qualify'
class InputOutputFormat(Expression):
2688class InputOutputFormat(Expression):
2689    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2693class Return(Expression):
2694    pass
key = 'return'
class Reference(Expression):
2697class Reference(Expression):
2698    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2701class Tuple(Expression):
2702    arg_types = {"expressions": False}
2703
2704    def isin(
2705        self,
2706        *expressions: t.Any,
2707        query: t.Optional[ExpOrStr] = None,
2708        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2709        copy: bool = True,
2710        **opts,
2711    ) -> In:
2712        return In(
2713            this=maybe_copy(self, copy),
2714            expressions=[convert(e, copy=copy) for e in expressions],
2715            query=maybe_parse(query, copy=copy, **opts) if query else None,
2716            unnest=(
2717                Unnest(
2718                    expressions=[
2719                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2720                        for e in ensure_list(unnest)
2721                    ]
2722                )
2723                if unnest
2724                else None
2725            ),
2726        )
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:
2704    def isin(
2705        self,
2706        *expressions: t.Any,
2707        query: t.Optional[ExpOrStr] = None,
2708        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2709        copy: bool = True,
2710        **opts,
2711    ) -> In:
2712        return In(
2713            this=maybe_copy(self, copy),
2714            expressions=[convert(e, copy=copy) for e in expressions],
2715            query=maybe_parse(query, copy=copy, **opts) if query else None,
2716            unnest=(
2717                Unnest(
2718                    expressions=[
2719                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2720                        for e in ensure_list(unnest)
2721                    ]
2722                )
2723                if unnest
2724                else None
2725            ),
2726        )
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):
2757class QueryOption(Expression):
2758    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2762class WithTableHint(Expression):
2763    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2767class IndexTableHint(Expression):
2768    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2772class HistoricalData(Expression):
2773    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2776class Table(Expression):
2777    arg_types = {
2778        "this": False,
2779        "alias": False,
2780        "db": False,
2781        "catalog": False,
2782        "laterals": False,
2783        "joins": False,
2784        "pivots": False,
2785        "hints": False,
2786        "system_time": False,
2787        "version": False,
2788        "format": False,
2789        "pattern": False,
2790        "ordinality": False,
2791        "when": False,
2792        "only": False,
2793    }
2794
2795    @property
2796    def name(self) -> str:
2797        if isinstance(self.this, Func):
2798            return ""
2799        return self.this.name
2800
2801    @property
2802    def db(self) -> str:
2803        return self.text("db")
2804
2805    @property
2806    def catalog(self) -> str:
2807        return self.text("catalog")
2808
2809    @property
2810    def selects(self) -> t.List[Expression]:
2811        return []
2812
2813    @property
2814    def named_selects(self) -> t.List[str]:
2815        return []
2816
2817    @property
2818    def parts(self) -> t.List[Expression]:
2819        """Return the parts of a table in order catalog, db, table."""
2820        parts: t.List[Expression] = []
2821
2822        for arg in ("catalog", "db", "this"):
2823            part = self.args.get(arg)
2824
2825            if isinstance(part, Dot):
2826                parts.extend(part.flatten())
2827            elif isinstance(part, Expression):
2828                parts.append(part)
2829
2830        return parts
2831
2832    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2833        parts = self.parts
2834        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2835        alias = self.args.get("alias")
2836        if alias:
2837            col = alias_(col, alias.this, copy=copy)
2838        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}
name: str
2795    @property
2796    def name(self) -> str:
2797        if isinstance(self.this, Func):
2798            return ""
2799        return self.this.name
db: str
2801    @property
2802    def db(self) -> str:
2803        return self.text("db")
catalog: str
2805    @property
2806    def catalog(self) -> str:
2807        return self.text("catalog")
selects: List[Expression]
2809    @property
2810    def selects(self) -> t.List[Expression]:
2811        return []
named_selects: List[str]
2813    @property
2814    def named_selects(self) -> t.List[str]:
2815        return []
parts: List[Expression]
2817    @property
2818    def parts(self) -> t.List[Expression]:
2819        """Return the parts of a table in order catalog, db, table."""
2820        parts: t.List[Expression] = []
2821
2822        for arg in ("catalog", "db", "this"):
2823            part = self.args.get(arg)
2824
2825            if isinstance(part, Dot):
2826                parts.extend(part.flatten())
2827            elif isinstance(part, Expression):
2828                parts.append(part)
2829
2830        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2832    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2833        parts = self.parts
2834        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2835        alias = self.args.get("alias")
2836        if alias:
2837            col = alias_(col, alias.this, copy=copy)
2838        return col
key = 'table'
class Union(Query):
2841class Union(Query):
2842    arg_types = {
2843        "with": False,
2844        "this": True,
2845        "expression": True,
2846        "distinct": False,
2847        "by_name": False,
2848        **QUERY_MODIFIERS,
2849    }
2850
2851    def select(
2852        self,
2853        *expressions: t.Optional[ExpOrStr],
2854        append: bool = True,
2855        dialect: DialectType = None,
2856        copy: bool = True,
2857        **opts,
2858    ) -> Union:
2859        this = maybe_copy(self, copy)
2860        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2861        this.expression.unnest().select(
2862            *expressions, append=append, dialect=dialect, copy=False, **opts
2863        )
2864        return this
2865
2866    @property
2867    def named_selects(self) -> t.List[str]:
2868        return self.this.unnest().named_selects
2869
2870    @property
2871    def is_star(self) -> bool:
2872        return self.this.is_star or self.expression.is_star
2873
2874    @property
2875    def selects(self) -> t.List[Expression]:
2876        return self.this.unnest().selects
2877
2878    @property
2879    def left(self) -> Expression:
2880        return self.this
2881
2882    @property
2883    def right(self) -> Expression:
2884        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:
2851    def select(
2852        self,
2853        *expressions: t.Optional[ExpOrStr],
2854        append: bool = True,
2855        dialect: DialectType = None,
2856        copy: bool = True,
2857        **opts,
2858    ) -> Union:
2859        this = maybe_copy(self, copy)
2860        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2861        this.expression.unnest().select(
2862            *expressions, append=append, dialect=dialect, copy=False, **opts
2863        )
2864        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]
2866    @property
2867    def named_selects(self) -> t.List[str]:
2868        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2870    @property
2871    def is_star(self) -> bool:
2872        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2874    @property
2875    def selects(self) -> t.List[Expression]:
2876        return self.this.unnest().selects

Returns the query's projections.

left: Expression
2878    @property
2879    def left(self) -> Expression:
2880        return self.this
right: Expression
2882    @property
2883    def right(self) -> Expression:
2884        return self.expression
key = 'union'
class Except(Union):
2887class Except(Union):
2888    pass
key = 'except'
class Intersect(Union):
2891class Intersect(Union):
2892    pass
key = 'intersect'
class Unnest(UDTF):
2895class Unnest(UDTF):
2896    arg_types = {
2897        "expressions": True,
2898        "alias": False,
2899        "offset": False,
2900    }
2901
2902    @property
2903    def selects(self) -> t.List[Expression]:
2904        columns = super().selects
2905        offset = self.args.get("offset")
2906        if offset:
2907            columns = columns + [to_identifier("offset") if offset is True else offset]
2908        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
2902    @property
2903    def selects(self) -> t.List[Expression]:
2904        columns = super().selects
2905        offset = self.args.get("offset")
2906        if offset:
2907            columns = columns + [to_identifier("offset") if offset is True else offset]
2908        return columns
key = 'unnest'
class Update(Expression):
2911class Update(Expression):
2912    arg_types = {
2913        "with": False,
2914        "this": False,
2915        "expressions": True,
2916        "from": False,
2917        "where": False,
2918        "returning": False,
2919        "order": False,
2920        "limit": False,
2921    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
2924class Values(UDTF):
2925    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
2928class Var(Expression):
2929    pass
key = 'var'
class Version(Expression):
2932class Version(Expression):
2933    """
2934    Time travel, iceberg, bigquery etc
2935    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2936    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2937    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2938    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2939    this is either TIMESTAMP or VERSION
2940    kind is ("AS OF", "BETWEEN")
2941    """
2942
2943    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
2946class Schema(Expression):
2947    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
2952class Lock(Expression):
2953    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
2956class Select(Query):
2957    arg_types = {
2958        "with": False,
2959        "kind": False,
2960        "expressions": False,
2961        "hint": False,
2962        "distinct": False,
2963        "into": False,
2964        "from": False,
2965        **QUERY_MODIFIERS,
2966    }
2967
2968    def from_(
2969        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2970    ) -> Select:
2971        """
2972        Set the FROM expression.
2973
2974        Example:
2975            >>> Select().from_("tbl").select("x").sql()
2976            'SELECT x FROM tbl'
2977
2978        Args:
2979            expression : the SQL code strings to parse.
2980                If a `From` instance is passed, this is used as-is.
2981                If another `Expression` instance is passed, it will be wrapped in a `From`.
2982            dialect: the dialect used to parse the input expression.
2983            copy: if `False`, modify this expression instance in-place.
2984            opts: other options to use to parse the input expressions.
2985
2986        Returns:
2987            The modified Select expression.
2988        """
2989        return _apply_builder(
2990            expression=expression,
2991            instance=self,
2992            arg="from",
2993            into=From,
2994            prefix="FROM",
2995            dialect=dialect,
2996            copy=copy,
2997            **opts,
2998        )
2999
3000    def group_by(
3001        self,
3002        *expressions: t.Optional[ExpOrStr],
3003        append: bool = True,
3004        dialect: DialectType = None,
3005        copy: bool = True,
3006        **opts,
3007    ) -> Select:
3008        """
3009        Set the GROUP BY expression.
3010
3011        Example:
3012            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3013            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3014
3015        Args:
3016            *expressions: the SQL code strings to parse.
3017                If a `Group` instance is passed, this is used as-is.
3018                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3019                If nothing is passed in then a group by is not applied to the expression
3020            append: if `True`, add to any existing expressions.
3021                Otherwise, this flattens all the `Group` expression into a single expression.
3022            dialect: the dialect used to parse the input expression.
3023            copy: if `False`, modify this expression instance in-place.
3024            opts: other options to use to parse the input expressions.
3025
3026        Returns:
3027            The modified Select expression.
3028        """
3029        if not expressions:
3030            return self if not copy else self.copy()
3031
3032        return _apply_child_list_builder(
3033            *expressions,
3034            instance=self,
3035            arg="group",
3036            append=append,
3037            copy=copy,
3038            prefix="GROUP BY",
3039            into=Group,
3040            dialect=dialect,
3041            **opts,
3042        )
3043
3044    def order_by(
3045        self,
3046        *expressions: t.Optional[ExpOrStr],
3047        append: bool = True,
3048        dialect: DialectType = None,
3049        copy: bool = True,
3050        **opts,
3051    ) -> Select:
3052        """
3053        Set the ORDER BY expression.
3054
3055        Example:
3056            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
3057            'SELECT x FROM tbl ORDER BY x DESC'
3058
3059        Args:
3060            *expressions: the SQL code strings to parse.
3061                If a `Group` instance is passed, this is used as-is.
3062                If another `Expression` instance is passed, it will be wrapped in a `Order`.
3063            append: if `True`, add to any existing expressions.
3064                Otherwise, this flattens all the `Order` expression into a single expression.
3065            dialect: the dialect used to parse the input expression.
3066            copy: if `False`, modify this expression instance in-place.
3067            opts: other options to use to parse the input expressions.
3068
3069        Returns:
3070            The modified Select expression.
3071        """
3072        return _apply_child_list_builder(
3073            *expressions,
3074            instance=self,
3075            arg="order",
3076            append=append,
3077            copy=copy,
3078            prefix="ORDER BY",
3079            into=Order,
3080            dialect=dialect,
3081            **opts,
3082        )
3083
3084    def sort_by(
3085        self,
3086        *expressions: t.Optional[ExpOrStr],
3087        append: bool = True,
3088        dialect: DialectType = None,
3089        copy: bool = True,
3090        **opts,
3091    ) -> Select:
3092        """
3093        Set the SORT BY expression.
3094
3095        Example:
3096            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3097            'SELECT x FROM tbl SORT BY x DESC'
3098
3099        Args:
3100            *expressions: the SQL code strings to parse.
3101                If a `Group` instance is passed, this is used as-is.
3102                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3103            append: if `True`, add to any existing expressions.
3104                Otherwise, this flattens all the `Order` expression into a single expression.
3105            dialect: the dialect used to parse the input expression.
3106            copy: if `False`, modify this expression instance in-place.
3107            opts: other options to use to parse the input expressions.
3108
3109        Returns:
3110            The modified Select expression.
3111        """
3112        return _apply_child_list_builder(
3113            *expressions,
3114            instance=self,
3115            arg="sort",
3116            append=append,
3117            copy=copy,
3118            prefix="SORT BY",
3119            into=Sort,
3120            dialect=dialect,
3121            **opts,
3122        )
3123
3124    def cluster_by(
3125        self,
3126        *expressions: t.Optional[ExpOrStr],
3127        append: bool = True,
3128        dialect: DialectType = None,
3129        copy: bool = True,
3130        **opts,
3131    ) -> Select:
3132        """
3133        Set the CLUSTER BY expression.
3134
3135        Example:
3136            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3137            'SELECT x FROM tbl CLUSTER BY x DESC'
3138
3139        Args:
3140            *expressions: the SQL code strings to parse.
3141                If a `Group` instance is passed, this is used as-is.
3142                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3143            append: if `True`, add to any existing expressions.
3144                Otherwise, this flattens all the `Order` expression into a single expression.
3145            dialect: the dialect used to parse the input expression.
3146            copy: if `False`, modify this expression instance in-place.
3147            opts: other options to use to parse the input expressions.
3148
3149        Returns:
3150            The modified Select expression.
3151        """
3152        return _apply_child_list_builder(
3153            *expressions,
3154            instance=self,
3155            arg="cluster",
3156            append=append,
3157            copy=copy,
3158            prefix="CLUSTER BY",
3159            into=Cluster,
3160            dialect=dialect,
3161            **opts,
3162        )
3163
3164    def limit(
3165        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3166    ) -> Select:
3167        return _apply_builder(
3168            expression=expression,
3169            instance=self,
3170            arg="limit",
3171            into=Limit,
3172            prefix="LIMIT",
3173            dialect=dialect,
3174            copy=copy,
3175            into_arg="expression",
3176            **opts,
3177        )
3178
3179    def offset(
3180        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3181    ) -> Select:
3182        """
3183        Set the OFFSET expression.
3184
3185        Example:
3186            >>> Select().from_("tbl").select("x").offset(10).sql()
3187            'SELECT x FROM tbl OFFSET 10'
3188
3189        Args:
3190            expression: the SQL code string to parse.
3191                This can also be an integer.
3192                If a `Offset` instance is passed, this is used as-is.
3193                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3194            dialect: the dialect used to parse the input expression.
3195            copy: if `False`, modify this expression instance in-place.
3196            opts: other options to use to parse the input expressions.
3197
3198        Returns:
3199            The modified Select expression.
3200        """
3201        return _apply_builder(
3202            expression=expression,
3203            instance=self,
3204            arg="offset",
3205            into=Offset,
3206            prefix="OFFSET",
3207            dialect=dialect,
3208            copy=copy,
3209            into_arg="expression",
3210            **opts,
3211        )
3212
3213    def select(
3214        self,
3215        *expressions: t.Optional[ExpOrStr],
3216        append: bool = True,
3217        dialect: DialectType = None,
3218        copy: bool = True,
3219        **opts,
3220    ) -> Select:
3221        return _apply_list_builder(
3222            *expressions,
3223            instance=self,
3224            arg="expressions",
3225            append=append,
3226            dialect=dialect,
3227            into=Expression,
3228            copy=copy,
3229            **opts,
3230        )
3231
3232    def lateral(
3233        self,
3234        *expressions: t.Optional[ExpOrStr],
3235        append: bool = True,
3236        dialect: DialectType = None,
3237        copy: bool = True,
3238        **opts,
3239    ) -> Select:
3240        """
3241        Append to or set the LATERAL expressions.
3242
3243        Example:
3244            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3245            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3246
3247        Args:
3248            *expressions: the SQL code strings to parse.
3249                If an `Expression` instance is passed, it will be used as-is.
3250            append: if `True`, add to any existing expressions.
3251                Otherwise, this resets the expressions.
3252            dialect: the dialect used to parse the input expressions.
3253            copy: if `False`, modify this expression instance in-place.
3254            opts: other options to use to parse the input expressions.
3255
3256        Returns:
3257            The modified Select expression.
3258        """
3259        return _apply_list_builder(
3260            *expressions,
3261            instance=self,
3262            arg="laterals",
3263            append=append,
3264            into=Lateral,
3265            prefix="LATERAL VIEW",
3266            dialect=dialect,
3267            copy=copy,
3268            **opts,
3269        )
3270
3271    def join(
3272        self,
3273        expression: ExpOrStr,
3274        on: t.Optional[ExpOrStr] = None,
3275        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3276        append: bool = True,
3277        join_type: t.Optional[str] = None,
3278        join_alias: t.Optional[Identifier | str] = None,
3279        dialect: DialectType = None,
3280        copy: bool = True,
3281        **opts,
3282    ) -> Select:
3283        """
3284        Append to or set the JOIN expressions.
3285
3286        Example:
3287            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3288            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3289
3290            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3291            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3292
3293            Use `join_type` to change the type of join:
3294
3295            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3296            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3297
3298        Args:
3299            expression: the SQL code string to parse.
3300                If an `Expression` instance is passed, it will be used as-is.
3301            on: optionally specify the join "on" criteria as a SQL string.
3302                If an `Expression` instance is passed, it will be used as-is.
3303            using: optionally specify the join "using" criteria as a SQL string.
3304                If an `Expression` instance is passed, it will be used as-is.
3305            append: if `True`, add to any existing expressions.
3306                Otherwise, this resets the expressions.
3307            join_type: if set, alter the parsed join type.
3308            join_alias: an optional alias for the joined source.
3309            dialect: the dialect used to parse the input expressions.
3310            copy: if `False`, modify this expression instance in-place.
3311            opts: other options to use to parse the input expressions.
3312
3313        Returns:
3314            Select: the modified expression.
3315        """
3316        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3317
3318        try:
3319            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3320        except ParseError:
3321            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3322
3323        join = expression if isinstance(expression, Join) else Join(this=expression)
3324
3325        if isinstance(join.this, Select):
3326            join.this.replace(join.this.subquery())
3327
3328        if join_type:
3329            method: t.Optional[Token]
3330            side: t.Optional[Token]
3331            kind: t.Optional[Token]
3332
3333            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3334
3335            if method:
3336                join.set("method", method.text)
3337            if side:
3338                join.set("side", side.text)
3339            if kind:
3340                join.set("kind", kind.text)
3341
3342        if on:
3343            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3344            join.set("on", on)
3345
3346        if using:
3347            join = _apply_list_builder(
3348                *ensure_list(using),
3349                instance=join,
3350                arg="using",
3351                append=append,
3352                copy=copy,
3353                into=Identifier,
3354                **opts,
3355            )
3356
3357        if join_alias:
3358            join.set("this", alias_(join.this, join_alias, table=True))
3359
3360        return _apply_list_builder(
3361            join,
3362            instance=self,
3363            arg="joins",
3364            append=append,
3365            copy=copy,
3366            **opts,
3367        )
3368
3369    def where(
3370        self,
3371        *expressions: t.Optional[ExpOrStr],
3372        append: bool = True,
3373        dialect: DialectType = None,
3374        copy: bool = True,
3375        **opts,
3376    ) -> Select:
3377        """
3378        Append to or set the WHERE expressions.
3379
3380        Example:
3381            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3382            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3383
3384        Args:
3385            *expressions: the SQL code strings to parse.
3386                If an `Expression` instance is passed, it will be used as-is.
3387                Multiple expressions are combined with an AND operator.
3388            append: if `True`, AND the new expressions to any existing expression.
3389                Otherwise, this resets the expression.
3390            dialect: the dialect used to parse the input expressions.
3391            copy: if `False`, modify this expression instance in-place.
3392            opts: other options to use to parse the input expressions.
3393
3394        Returns:
3395            Select: the modified expression.
3396        """
3397        return _apply_conjunction_builder(
3398            *expressions,
3399            instance=self,
3400            arg="where",
3401            append=append,
3402            into=Where,
3403            dialect=dialect,
3404            copy=copy,
3405            **opts,
3406        )
3407
3408    def having(
3409        self,
3410        *expressions: t.Optional[ExpOrStr],
3411        append: bool = True,
3412        dialect: DialectType = None,
3413        copy: bool = True,
3414        **opts,
3415    ) -> Select:
3416        """
3417        Append to or set the HAVING expressions.
3418
3419        Example:
3420            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3421            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3422
3423        Args:
3424            *expressions: the SQL code strings to parse.
3425                If an `Expression` instance is passed, it will be used as-is.
3426                Multiple expressions are combined with an AND operator.
3427            append: if `True`, AND the new expressions to any existing expression.
3428                Otherwise, this resets the expression.
3429            dialect: the dialect used to parse the input expressions.
3430            copy: if `False`, modify this expression instance in-place.
3431            opts: other options to use to parse the input expressions.
3432
3433        Returns:
3434            The modified Select expression.
3435        """
3436        return _apply_conjunction_builder(
3437            *expressions,
3438            instance=self,
3439            arg="having",
3440            append=append,
3441            into=Having,
3442            dialect=dialect,
3443            copy=copy,
3444            **opts,
3445        )
3446
3447    def window(
3448        self,
3449        *expressions: t.Optional[ExpOrStr],
3450        append: bool = True,
3451        dialect: DialectType = None,
3452        copy: bool = True,
3453        **opts,
3454    ) -> Select:
3455        return _apply_list_builder(
3456            *expressions,
3457            instance=self,
3458            arg="windows",
3459            append=append,
3460            into=Window,
3461            dialect=dialect,
3462            copy=copy,
3463            **opts,
3464        )
3465
3466    def qualify(
3467        self,
3468        *expressions: t.Optional[ExpOrStr],
3469        append: bool = True,
3470        dialect: DialectType = None,
3471        copy: bool = True,
3472        **opts,
3473    ) -> Select:
3474        return _apply_conjunction_builder(
3475            *expressions,
3476            instance=self,
3477            arg="qualify",
3478            append=append,
3479            into=Qualify,
3480            dialect=dialect,
3481            copy=copy,
3482            **opts,
3483        )
3484
3485    def distinct(
3486        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3487    ) -> Select:
3488        """
3489        Set the OFFSET expression.
3490
3491        Example:
3492            >>> Select().from_("tbl").select("x").distinct().sql()
3493            'SELECT DISTINCT x FROM tbl'
3494
3495        Args:
3496            ons: the expressions to distinct on
3497            distinct: whether the Select should be distinct
3498            copy: if `False`, modify this expression instance in-place.
3499
3500        Returns:
3501            Select: the modified expression.
3502        """
3503        instance = maybe_copy(self, copy)
3504        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3505        instance.set("distinct", Distinct(on=on) if distinct else None)
3506        return instance
3507
3508    def ctas(
3509        self,
3510        table: ExpOrStr,
3511        properties: t.Optional[t.Dict] = None,
3512        dialect: DialectType = None,
3513        copy: bool = True,
3514        **opts,
3515    ) -> Create:
3516        """
3517        Convert this expression to a CREATE TABLE AS statement.
3518
3519        Example:
3520            >>> Select().select("*").from_("tbl").ctas("x").sql()
3521            'CREATE TABLE x AS SELECT * FROM tbl'
3522
3523        Args:
3524            table: the SQL code string to parse as the table name.
3525                If another `Expression` instance is passed, it will be used as-is.
3526            properties: an optional mapping of table properties
3527            dialect: the dialect used to parse the input table.
3528            copy: if `False`, modify this expression instance in-place.
3529            opts: other options to use to parse the input table.
3530
3531        Returns:
3532            The new Create expression.
3533        """
3534        instance = maybe_copy(self, copy)
3535        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3536
3537        properties_expression = None
3538        if properties:
3539            properties_expression = Properties.from_dict(properties)
3540
3541        return Create(
3542            this=table_expression,
3543            kind="TABLE",
3544            expression=instance,
3545            properties=properties_expression,
3546        )
3547
3548    def lock(self, update: bool = True, copy: bool = True) -> Select:
3549        """
3550        Set the locking read mode for this expression.
3551
3552        Examples:
3553            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3554            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3555
3556            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3557            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3558
3559        Args:
3560            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3561            copy: if `False`, modify this expression instance in-place.
3562
3563        Returns:
3564            The modified expression.
3565        """
3566        inst = maybe_copy(self, copy)
3567        inst.set("locks", [Lock(update=update)])
3568
3569        return inst
3570
3571    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3572        """
3573        Set hints for this expression.
3574
3575        Examples:
3576            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3577            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3578
3579        Args:
3580            hints: The SQL code strings to parse as the hints.
3581                If an `Expression` instance is passed, it will be used as-is.
3582            dialect: The dialect used to parse the hints.
3583            copy: If `False`, modify this expression instance in-place.
3584
3585        Returns:
3586            The modified expression.
3587        """
3588        inst = maybe_copy(self, copy)
3589        inst.set(
3590            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3591        )
3592
3593        return inst
3594
3595    @property
3596    def named_selects(self) -> t.List[str]:
3597        return [e.output_name for e in self.expressions if e.alias_or_name]
3598
3599    @property
3600    def is_star(self) -> bool:
3601        return any(expression.is_star for expression in self.expressions)
3602
3603    @property
3604    def selects(self) -> t.List[Expression]:
3605        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:
2968    def from_(
2969        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2970    ) -> Select:
2971        """
2972        Set the FROM expression.
2973
2974        Example:
2975            >>> Select().from_("tbl").select("x").sql()
2976            'SELECT x FROM tbl'
2977
2978        Args:
2979            expression : the SQL code strings to parse.
2980                If a `From` instance is passed, this is used as-is.
2981                If another `Expression` instance is passed, it will be wrapped in a `From`.
2982            dialect: the dialect used to parse the input expression.
2983            copy: if `False`, modify this expression instance in-place.
2984            opts: other options to use to parse the input expressions.
2985
2986        Returns:
2987            The modified Select expression.
2988        """
2989        return _apply_builder(
2990            expression=expression,
2991            instance=self,
2992            arg="from",
2993            into=From,
2994            prefix="FROM",
2995            dialect=dialect,
2996            copy=copy,
2997            **opts,
2998        )

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:
3000    def group_by(
3001        self,
3002        *expressions: t.Optional[ExpOrStr],
3003        append: bool = True,
3004        dialect: DialectType = None,
3005        copy: bool = True,
3006        **opts,
3007    ) -> Select:
3008        """
3009        Set the GROUP BY expression.
3010
3011        Example:
3012            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3013            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3014
3015        Args:
3016            *expressions: the SQL code strings to parse.
3017                If a `Group` instance is passed, this is used as-is.
3018                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3019                If nothing is passed in then a group by is not applied to the expression
3020            append: if `True`, add to any existing expressions.
3021                Otherwise, this flattens all the `Group` expression into a single expression.
3022            dialect: the dialect used to parse the input expression.
3023            copy: if `False`, modify this expression instance in-place.
3024            opts: other options to use to parse the input expressions.
3025
3026        Returns:
3027            The modified Select expression.
3028        """
3029        if not expressions:
3030            return self if not copy else self.copy()
3031
3032        return _apply_child_list_builder(
3033            *expressions,
3034            instance=self,
3035            arg="group",
3036            append=append,
3037            copy=copy,
3038            prefix="GROUP BY",
3039            into=Group,
3040            dialect=dialect,
3041            **opts,
3042        )

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 order_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:
3044    def order_by(
3045        self,
3046        *expressions: t.Optional[ExpOrStr],
3047        append: bool = True,
3048        dialect: DialectType = None,
3049        copy: bool = True,
3050        **opts,
3051    ) -> Select:
3052        """
3053        Set the ORDER BY expression.
3054
3055        Example:
3056            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
3057            'SELECT x FROM tbl ORDER BY x DESC'
3058
3059        Args:
3060            *expressions: the SQL code strings to parse.
3061                If a `Group` instance is passed, this is used as-is.
3062                If another `Expression` instance is passed, it will be wrapped in a `Order`.
3063            append: if `True`, add to any existing expressions.
3064                Otherwise, this flattens all the `Order` expression into a single expression.
3065            dialect: the dialect used to parse the input expression.
3066            copy: if `False`, modify this expression instance in-place.
3067            opts: other options to use to parse the input expressions.
3068
3069        Returns:
3070            The modified Select expression.
3071        """
3072        return _apply_child_list_builder(
3073            *expressions,
3074            instance=self,
3075            arg="order",
3076            append=append,
3077            copy=copy,
3078            prefix="ORDER BY",
3079            into=Order,
3080            dialect=dialect,
3081            **opts,
3082        )

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.

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:
3084    def sort_by(
3085        self,
3086        *expressions: t.Optional[ExpOrStr],
3087        append: bool = True,
3088        dialect: DialectType = None,
3089        copy: bool = True,
3090        **opts,
3091    ) -> Select:
3092        """
3093        Set the SORT BY expression.
3094
3095        Example:
3096            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3097            'SELECT x FROM tbl SORT BY x DESC'
3098
3099        Args:
3100            *expressions: the SQL code strings to parse.
3101                If a `Group` instance is passed, this is used as-is.
3102                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3103            append: if `True`, add to any existing expressions.
3104                Otherwise, this flattens all the `Order` expression into a single expression.
3105            dialect: the dialect used to parse the input expression.
3106            copy: if `False`, modify this expression instance in-place.
3107            opts: other options to use to parse the input expressions.
3108
3109        Returns:
3110            The modified Select expression.
3111        """
3112        return _apply_child_list_builder(
3113            *expressions,
3114            instance=self,
3115            arg="sort",
3116            append=append,
3117            copy=copy,
3118            prefix="SORT BY",
3119            into=Sort,
3120            dialect=dialect,
3121            **opts,
3122        )

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:
3124    def cluster_by(
3125        self,
3126        *expressions: t.Optional[ExpOrStr],
3127        append: bool = True,
3128        dialect: DialectType = None,
3129        copy: bool = True,
3130        **opts,
3131    ) -> Select:
3132        """
3133        Set the CLUSTER BY expression.
3134
3135        Example:
3136            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3137            'SELECT x FROM tbl CLUSTER BY x DESC'
3138
3139        Args:
3140            *expressions: the SQL code strings to parse.
3141                If a `Group` instance is passed, this is used as-is.
3142                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3143            append: if `True`, add to any existing expressions.
3144                Otherwise, this flattens all the `Order` expression into a single expression.
3145            dialect: the dialect used to parse the input expression.
3146            copy: if `False`, modify this expression instance in-place.
3147            opts: other options to use to parse the input expressions.
3148
3149        Returns:
3150            The modified Select expression.
3151        """
3152        return _apply_child_list_builder(
3153            *expressions,
3154            instance=self,
3155            arg="cluster",
3156            append=append,
3157            copy=copy,
3158            prefix="CLUSTER BY",
3159            into=Cluster,
3160            dialect=dialect,
3161            **opts,
3162        )

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 limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3164    def limit(
3165        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3166    ) -> Select:
3167        return _apply_builder(
3168            expression=expression,
3169            instance=self,
3170            arg="limit",
3171            into=Limit,
3172            prefix="LIMIT",
3173            dialect=dialect,
3174            copy=copy,
3175            into_arg="expression",
3176            **opts,
3177        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 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, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3179    def offset(
3180        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3181    ) -> Select:
3182        """
3183        Set the OFFSET expression.
3184
3185        Example:
3186            >>> Select().from_("tbl").select("x").offset(10).sql()
3187            'SELECT x FROM tbl OFFSET 10'
3188
3189        Args:
3190            expression: the SQL code string to parse.
3191                This can also be an integer.
3192                If a `Offset` instance is passed, this is used as-is.
3193                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3194            dialect: the dialect used to parse the input expression.
3195            copy: if `False`, modify this expression instance in-place.
3196            opts: other options to use to parse the input expressions.
3197
3198        Returns:
3199            The modified Select expression.
3200        """
3201        return _apply_builder(
3202            expression=expression,
3203            instance=self,
3204            arg="offset",
3205            into=Offset,
3206            prefix="OFFSET",
3207            dialect=dialect,
3208            copy=copy,
3209            into_arg="expression",
3210            **opts,
3211        )

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 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:
3213    def select(
3214        self,
3215        *expressions: t.Optional[ExpOrStr],
3216        append: bool = True,
3217        dialect: DialectType = None,
3218        copy: bool = True,
3219        **opts,
3220    ) -> Select:
3221        return _apply_list_builder(
3222            *expressions,
3223            instance=self,
3224            arg="expressions",
3225            append=append,
3226            dialect=dialect,
3227            into=Expression,
3228            copy=copy,
3229            **opts,
3230        )

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:
3232    def lateral(
3233        self,
3234        *expressions: t.Optional[ExpOrStr],
3235        append: bool = True,
3236        dialect: DialectType = None,
3237        copy: bool = True,
3238        **opts,
3239    ) -> Select:
3240        """
3241        Append to or set the LATERAL expressions.
3242
3243        Example:
3244            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3245            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3246
3247        Args:
3248            *expressions: the SQL code strings to parse.
3249                If an `Expression` instance is passed, it will be used as-is.
3250            append: if `True`, add to any existing expressions.
3251                Otherwise, this resets the expressions.
3252            dialect: the dialect used to parse the input expressions.
3253            copy: if `False`, modify this expression instance in-place.
3254            opts: other options to use to parse the input expressions.
3255
3256        Returns:
3257            The modified Select expression.
3258        """
3259        return _apply_list_builder(
3260            *expressions,
3261            instance=self,
3262            arg="laterals",
3263            append=append,
3264            into=Lateral,
3265            prefix="LATERAL VIEW",
3266            dialect=dialect,
3267            copy=copy,
3268            **opts,
3269        )

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:
3271    def join(
3272        self,
3273        expression: ExpOrStr,
3274        on: t.Optional[ExpOrStr] = None,
3275        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3276        append: bool = True,
3277        join_type: t.Optional[str] = None,
3278        join_alias: t.Optional[Identifier | str] = None,
3279        dialect: DialectType = None,
3280        copy: bool = True,
3281        **opts,
3282    ) -> Select:
3283        """
3284        Append to or set the JOIN expressions.
3285
3286        Example:
3287            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3288            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3289
3290            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3291            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3292
3293            Use `join_type` to change the type of join:
3294
3295            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3296            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3297
3298        Args:
3299            expression: the SQL code string to parse.
3300                If an `Expression` instance is passed, it will be used as-is.
3301            on: optionally specify the join "on" criteria as a SQL string.
3302                If an `Expression` instance is passed, it will be used as-is.
3303            using: optionally specify the join "using" criteria as a SQL string.
3304                If an `Expression` instance is passed, it will be used as-is.
3305            append: if `True`, add to any existing expressions.
3306                Otherwise, this resets the expressions.
3307            join_type: if set, alter the parsed join type.
3308            join_alias: an optional alias for the joined source.
3309            dialect: the dialect used to parse the input expressions.
3310            copy: if `False`, modify this expression instance in-place.
3311            opts: other options to use to parse the input expressions.
3312
3313        Returns:
3314            Select: the modified expression.
3315        """
3316        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3317
3318        try:
3319            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3320        except ParseError:
3321            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3322
3323        join = expression if isinstance(expression, Join) else Join(this=expression)
3324
3325        if isinstance(join.this, Select):
3326            join.this.replace(join.this.subquery())
3327
3328        if join_type:
3329            method: t.Optional[Token]
3330            side: t.Optional[Token]
3331            kind: t.Optional[Token]
3332
3333            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3334
3335            if method:
3336                join.set("method", method.text)
3337            if side:
3338                join.set("side", side.text)
3339            if kind:
3340                join.set("kind", kind.text)
3341
3342        if on:
3343            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3344            join.set("on", on)
3345
3346        if using:
3347            join = _apply_list_builder(
3348                *ensure_list(using),
3349                instance=join,
3350                arg="using",
3351                append=append,
3352                copy=copy,
3353                into=Identifier,
3354                **opts,
3355            )
3356
3357        if join_alias:
3358            join.set("this", alias_(join.this, join_alias, table=True))
3359
3360        return _apply_list_builder(
3361            join,
3362            instance=self,
3363            arg="joins",
3364            append=append,
3365            copy=copy,
3366            **opts,
3367        )

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:
3369    def where(
3370        self,
3371        *expressions: t.Optional[ExpOrStr],
3372        append: bool = True,
3373        dialect: DialectType = None,
3374        copy: bool = True,
3375        **opts,
3376    ) -> Select:
3377        """
3378        Append to or set the WHERE expressions.
3379
3380        Example:
3381            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3382            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3383
3384        Args:
3385            *expressions: the SQL code strings to parse.
3386                If an `Expression` instance is passed, it will be used as-is.
3387                Multiple expressions are combined with an AND operator.
3388            append: if `True`, AND the new expressions to any existing expression.
3389                Otherwise, this resets the expression.
3390            dialect: the dialect used to parse the input expressions.
3391            copy: if `False`, modify this expression instance in-place.
3392            opts: other options to use to parse the input expressions.
3393
3394        Returns:
3395            Select: the modified expression.
3396        """
3397        return _apply_conjunction_builder(
3398            *expressions,
3399            instance=self,
3400            arg="where",
3401            append=append,
3402            into=Where,
3403            dialect=dialect,
3404            copy=copy,
3405            **opts,
3406        )

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:
3408    def having(
3409        self,
3410        *expressions: t.Optional[ExpOrStr],
3411        append: bool = True,
3412        dialect: DialectType = None,
3413        copy: bool = True,
3414        **opts,
3415    ) -> Select:
3416        """
3417        Append to or set the HAVING expressions.
3418
3419        Example:
3420            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3421            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3422
3423        Args:
3424            *expressions: the SQL code strings to parse.
3425                If an `Expression` instance is passed, it will be used as-is.
3426                Multiple expressions are combined with an AND operator.
3427            append: if `True`, AND the new expressions to any existing expression.
3428                Otherwise, this resets the expression.
3429            dialect: the dialect used to parse the input expressions.
3430            copy: if `False`, modify this expression instance in-place.
3431            opts: other options to use to parse the input expressions.
3432
3433        Returns:
3434            The modified Select expression.
3435        """
3436        return _apply_conjunction_builder(
3437            *expressions,
3438            instance=self,
3439            arg="having",
3440            append=append,
3441            into=Having,
3442            dialect=dialect,
3443            copy=copy,
3444            **opts,
3445        )

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:
3447    def window(
3448        self,
3449        *expressions: t.Optional[ExpOrStr],
3450        append: bool = True,
3451        dialect: DialectType = None,
3452        copy: bool = True,
3453        **opts,
3454    ) -> Select:
3455        return _apply_list_builder(
3456            *expressions,
3457            instance=self,
3458            arg="windows",
3459            append=append,
3460            into=Window,
3461            dialect=dialect,
3462            copy=copy,
3463            **opts,
3464        )
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:
3466    def qualify(
3467        self,
3468        *expressions: t.Optional[ExpOrStr],
3469        append: bool = True,
3470        dialect: DialectType = None,
3471        copy: bool = True,
3472        **opts,
3473    ) -> Select:
3474        return _apply_conjunction_builder(
3475            *expressions,
3476            instance=self,
3477            arg="qualify",
3478            append=append,
3479            into=Qualify,
3480            dialect=dialect,
3481            copy=copy,
3482            **opts,
3483        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3485    def distinct(
3486        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3487    ) -> Select:
3488        """
3489        Set the OFFSET expression.
3490
3491        Example:
3492            >>> Select().from_("tbl").select("x").distinct().sql()
3493            'SELECT DISTINCT x FROM tbl'
3494
3495        Args:
3496            ons: the expressions to distinct on
3497            distinct: whether the Select should be distinct
3498            copy: if `False`, modify this expression instance in-place.
3499
3500        Returns:
3501            Select: the modified expression.
3502        """
3503        instance = maybe_copy(self, copy)
3504        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3505        instance.set("distinct", Distinct(on=on) if distinct else None)
3506        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:
3508    def ctas(
3509        self,
3510        table: ExpOrStr,
3511        properties: t.Optional[t.Dict] = None,
3512        dialect: DialectType = None,
3513        copy: bool = True,
3514        **opts,
3515    ) -> Create:
3516        """
3517        Convert this expression to a CREATE TABLE AS statement.
3518
3519        Example:
3520            >>> Select().select("*").from_("tbl").ctas("x").sql()
3521            'CREATE TABLE x AS SELECT * FROM tbl'
3522
3523        Args:
3524            table: the SQL code string to parse as the table name.
3525                If another `Expression` instance is passed, it will be used as-is.
3526            properties: an optional mapping of table properties
3527            dialect: the dialect used to parse the input table.
3528            copy: if `False`, modify this expression instance in-place.
3529            opts: other options to use to parse the input table.
3530
3531        Returns:
3532            The new Create expression.
3533        """
3534        instance = maybe_copy(self, copy)
3535        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3536
3537        properties_expression = None
3538        if properties:
3539            properties_expression = Properties.from_dict(properties)
3540
3541        return Create(
3542            this=table_expression,
3543            kind="TABLE",
3544            expression=instance,
3545            properties=properties_expression,
3546        )

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:
3548    def lock(self, update: bool = True, copy: bool = True) -> Select:
3549        """
3550        Set the locking read mode for this expression.
3551
3552        Examples:
3553            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3554            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3555
3556            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3557            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3558
3559        Args:
3560            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3561            copy: if `False`, modify this expression instance in-place.
3562
3563        Returns:
3564            The modified expression.
3565        """
3566        inst = maybe_copy(self, copy)
3567        inst.set("locks", [Lock(update=update)])
3568
3569        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:
3571    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3572        """
3573        Set hints for this expression.
3574
3575        Examples:
3576            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3577            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3578
3579        Args:
3580            hints: The SQL code strings to parse as the hints.
3581                If an `Expression` instance is passed, it will be used as-is.
3582            dialect: The dialect used to parse the hints.
3583            copy: If `False`, modify this expression instance in-place.
3584
3585        Returns:
3586            The modified expression.
3587        """
3588        inst = maybe_copy(self, copy)
3589        inst.set(
3590            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3591        )
3592
3593        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]
3595    @property
3596    def named_selects(self) -> t.List[str]:
3597        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
3599    @property
3600    def is_star(self) -> bool:
3601        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3603    @property
3604    def selects(self) -> t.List[Expression]:
3605        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3611class Subquery(DerivedTable, Query):
3612    arg_types = {
3613        "this": True,
3614        "alias": False,
3615        "with": False,
3616        **QUERY_MODIFIERS,
3617    }
3618
3619    def unnest(self):
3620        """Returns the first non subquery."""
3621        expression = self
3622        while isinstance(expression, Subquery):
3623            expression = expression.this
3624        return expression
3625
3626    def unwrap(self) -> Subquery:
3627        expression = self
3628        while expression.same_parent and expression.is_wrapper:
3629            expression = t.cast(Subquery, expression.parent)
3630        return expression
3631
3632    def select(
3633        self,
3634        *expressions: t.Optional[ExpOrStr],
3635        append: bool = True,
3636        dialect: DialectType = None,
3637        copy: bool = True,
3638        **opts,
3639    ) -> Subquery:
3640        this = maybe_copy(self, copy)
3641        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3642        return this
3643
3644    @property
3645    def is_wrapper(self) -> bool:
3646        """
3647        Whether this Subquery acts as a simple wrapper around another expression.
3648
3649        SELECT * FROM (((SELECT * FROM t)))
3650                      ^
3651                      This corresponds to a "wrapper" Subquery node
3652        """
3653        return all(v is None for k, v in self.args.items() if k != "this")
3654
3655    @property
3656    def is_star(self) -> bool:
3657        return self.this.is_star
3658
3659    @property
3660    def output_name(self) -> str:
3661        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):
3619    def unnest(self):
3620        """Returns the first non subquery."""
3621        expression = self
3622        while isinstance(expression, Subquery):
3623            expression = expression.this
3624        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3626    def unwrap(self) -> Subquery:
3627        expression = self
3628        while expression.same_parent and expression.is_wrapper:
3629            expression = t.cast(Subquery, expression.parent)
3630        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:
3632    def select(
3633        self,
3634        *expressions: t.Optional[ExpOrStr],
3635        append: bool = True,
3636        dialect: DialectType = None,
3637        copy: bool = True,
3638        **opts,
3639    ) -> Subquery:
3640        this = maybe_copy(self, copy)
3641        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3642        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
3644    @property
3645    def is_wrapper(self) -> bool:
3646        """
3647        Whether this Subquery acts as a simple wrapper around another expression.
3648
3649        SELECT * FROM (((SELECT * FROM t)))
3650                      ^
3651                      This corresponds to a "wrapper" Subquery node
3652        """
3653        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
3655    @property
3656    def is_star(self) -> bool:
3657        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3659    @property
3660    def output_name(self) -> str:
3661        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):
3664class TableSample(Expression):
3665    arg_types = {
3666        "this": False,
3667        "expressions": False,
3668        "method": False,
3669        "bucket_numerator": False,
3670        "bucket_denominator": False,
3671        "bucket_field": False,
3672        "percent": False,
3673        "rows": False,
3674        "size": False,
3675        "seed": False,
3676    }
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):
3679class Tag(Expression):
3680    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3681
3682    arg_types = {
3683        "this": False,
3684        "prefix": False,
3685        "postfix": False,
3686    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3691class Pivot(Expression):
3692    arg_types = {
3693        "this": False,
3694        "alias": False,
3695        "expressions": False,
3696        "field": False,
3697        "unpivot": False,
3698        "using": False,
3699        "group": False,
3700        "columns": False,
3701        "include_nulls": False,
3702    }
3703
3704    @property
3705    def unpivot(self) -> bool:
3706        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
3704    @property
3705    def unpivot(self) -> bool:
3706        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3709class Window(Condition):
3710    arg_types = {
3711        "this": True,
3712        "partition_by": False,
3713        "order": False,
3714        "spec": False,
3715        "alias": False,
3716        "over": False,
3717        "first": False,
3718    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3721class WindowSpec(Expression):
3722    arg_types = {
3723        "kind": False,
3724        "start": False,
3725        "start_side": False,
3726        "end": False,
3727        "end_side": False,
3728    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3731class PreWhere(Expression):
3732    pass
key = 'prewhere'
class Where(Expression):
3735class Where(Expression):
3736    pass
key = 'where'
class Star(Expression):
3739class Star(Expression):
3740    arg_types = {"except": False, "replace": False}
3741
3742    @property
3743    def name(self) -> str:
3744        return "*"
3745
3746    @property
3747    def output_name(self) -> str:
3748        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3742    @property
3743    def name(self) -> str:
3744        return "*"
output_name: str
3746    @property
3747    def output_name(self) -> str:
3748        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):
3751class Parameter(Condition):
3752    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3755class SessionParameter(Condition):
3756    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3759class Placeholder(Condition):
3760    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3763class Null(Condition):
3764    arg_types: t.Dict[str, t.Any] = {}
3765
3766    @property
3767    def name(self) -> str:
3768        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3766    @property
3767    def name(self) -> str:
3768        return "NULL"
key = 'null'
class Boolean(Condition):
3771class Boolean(Condition):
3772    pass
key = 'boolean'
class DataTypeParam(Expression):
3775class DataTypeParam(Expression):
3776    arg_types = {"this": True, "expression": False}
3777
3778    @property
3779    def name(self) -> str:
3780        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3778    @property
3779    def name(self) -> str:
3780        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3783class DataType(Expression):
3784    arg_types = {
3785        "this": True,
3786        "expressions": False,
3787        "nested": False,
3788        "values": False,
3789        "prefix": False,
3790        "kind": False,
3791    }
3792
3793    class Type(AutoName):
3794        ARRAY = auto()
3795        AGGREGATEFUNCTION = auto()
3796        SIMPLEAGGREGATEFUNCTION = auto()
3797        BIGDECIMAL = auto()
3798        BIGINT = auto()
3799        BIGSERIAL = auto()
3800        BINARY = auto()
3801        BIT = auto()
3802        BOOLEAN = auto()
3803        BPCHAR = auto()
3804        CHAR = auto()
3805        DATE = auto()
3806        DATE32 = auto()
3807        DATEMULTIRANGE = auto()
3808        DATERANGE = auto()
3809        DATETIME = auto()
3810        DATETIME64 = auto()
3811        DECIMAL = auto()
3812        DOUBLE = auto()
3813        ENUM = auto()
3814        ENUM8 = auto()
3815        ENUM16 = auto()
3816        FIXEDSTRING = auto()
3817        FLOAT = auto()
3818        GEOGRAPHY = auto()
3819        GEOMETRY = auto()
3820        HLLSKETCH = auto()
3821        HSTORE = auto()
3822        IMAGE = auto()
3823        INET = auto()
3824        INT = auto()
3825        INT128 = auto()
3826        INT256 = auto()
3827        INT4MULTIRANGE = auto()
3828        INT4RANGE = auto()
3829        INT8MULTIRANGE = auto()
3830        INT8RANGE = auto()
3831        INTERVAL = auto()
3832        IPADDRESS = auto()
3833        IPPREFIX = auto()
3834        IPV4 = auto()
3835        IPV6 = auto()
3836        JSON = auto()
3837        JSONB = auto()
3838        LONGBLOB = auto()
3839        LONGTEXT = auto()
3840        LOWCARDINALITY = auto()
3841        MAP = auto()
3842        MEDIUMBLOB = auto()
3843        MEDIUMINT = auto()
3844        MEDIUMTEXT = auto()
3845        MONEY = auto()
3846        NAME = auto()
3847        NCHAR = auto()
3848        NESTED = auto()
3849        NULL = auto()
3850        NULLABLE = auto()
3851        NUMMULTIRANGE = auto()
3852        NUMRANGE = auto()
3853        NVARCHAR = auto()
3854        OBJECT = auto()
3855        ROWVERSION = auto()
3856        SERIAL = auto()
3857        SET = auto()
3858        SMALLINT = auto()
3859        SMALLMONEY = auto()
3860        SMALLSERIAL = auto()
3861        STRUCT = auto()
3862        SUPER = auto()
3863        TEXT = auto()
3864        TINYBLOB = auto()
3865        TINYTEXT = auto()
3866        TIME = auto()
3867        TIMETZ = auto()
3868        TIMESTAMP = auto()
3869        TIMESTAMPLTZ = auto()
3870        TIMESTAMPTZ = auto()
3871        TIMESTAMP_S = auto()
3872        TIMESTAMP_MS = auto()
3873        TIMESTAMP_NS = auto()
3874        TINYINT = auto()
3875        TSMULTIRANGE = auto()
3876        TSRANGE = auto()
3877        TSTZMULTIRANGE = auto()
3878        TSTZRANGE = auto()
3879        UBIGINT = auto()
3880        UINT = auto()
3881        UINT128 = auto()
3882        UINT256 = auto()
3883        UMEDIUMINT = auto()
3884        UDECIMAL = auto()
3885        UNIQUEIDENTIFIER = auto()
3886        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3887        USERDEFINED = "USER-DEFINED"
3888        USMALLINT = auto()
3889        UTINYINT = auto()
3890        UUID = auto()
3891        VARBINARY = auto()
3892        VARCHAR = auto()
3893        VARIANT = auto()
3894        XML = auto()
3895        YEAR = auto()
3896
3897    STRUCT_TYPES = {
3898        Type.NESTED,
3899        Type.OBJECT,
3900        Type.STRUCT,
3901    }
3902
3903    NESTED_TYPES = {
3904        *STRUCT_TYPES,
3905        Type.ARRAY,
3906        Type.MAP,
3907    }
3908
3909    TEXT_TYPES = {
3910        Type.CHAR,
3911        Type.NCHAR,
3912        Type.NVARCHAR,
3913        Type.TEXT,
3914        Type.VARCHAR,
3915        Type.NAME,
3916    }
3917
3918    INTEGER_TYPES = {
3919        Type.BIGINT,
3920        Type.BIT,
3921        Type.INT,
3922        Type.INT128,
3923        Type.INT256,
3924        Type.MEDIUMINT,
3925        Type.SMALLINT,
3926        Type.TINYINT,
3927        Type.UBIGINT,
3928        Type.UINT,
3929        Type.UINT128,
3930        Type.UINT256,
3931        Type.UMEDIUMINT,
3932        Type.USMALLINT,
3933        Type.UTINYINT,
3934    }
3935
3936    FLOAT_TYPES = {
3937        Type.DOUBLE,
3938        Type.FLOAT,
3939    }
3940
3941    REAL_TYPES = {
3942        *FLOAT_TYPES,
3943        Type.BIGDECIMAL,
3944        Type.DECIMAL,
3945        Type.MONEY,
3946        Type.SMALLMONEY,
3947        Type.UDECIMAL,
3948    }
3949
3950    NUMERIC_TYPES = {
3951        *INTEGER_TYPES,
3952        *REAL_TYPES,
3953    }
3954
3955    TEMPORAL_TYPES = {
3956        Type.DATE,
3957        Type.DATE32,
3958        Type.DATETIME,
3959        Type.DATETIME64,
3960        Type.TIME,
3961        Type.TIMESTAMP,
3962        Type.TIMESTAMPLTZ,
3963        Type.TIMESTAMPTZ,
3964        Type.TIMESTAMP_MS,
3965        Type.TIMESTAMP_NS,
3966        Type.TIMESTAMP_S,
3967        Type.TIMETZ,
3968    }
3969
3970    @classmethod
3971    def build(
3972        cls,
3973        dtype: DATA_TYPE,
3974        dialect: DialectType = None,
3975        udt: bool = False,
3976        copy: bool = True,
3977        **kwargs,
3978    ) -> DataType:
3979        """
3980        Constructs a DataType object.
3981
3982        Args:
3983            dtype: the data type of interest.
3984            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3985            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3986                DataType, thus creating a user-defined type.
3987            copy: whether to copy the data type.
3988            kwargs: additional arguments to pass in the constructor of DataType.
3989
3990        Returns:
3991            The constructed DataType object.
3992        """
3993        from sqlglot import parse_one
3994
3995        if isinstance(dtype, str):
3996            if dtype.upper() == "UNKNOWN":
3997                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3998
3999            try:
4000                data_type_exp = parse_one(
4001                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4002                )
4003            except ParseError:
4004                if udt:
4005                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4006                raise
4007        elif isinstance(dtype, DataType.Type):
4008            data_type_exp = DataType(this=dtype)
4009        elif isinstance(dtype, DataType):
4010            return maybe_copy(dtype, copy)
4011        else:
4012            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4013
4014        return DataType(**{**data_type_exp.args, **kwargs})
4015
4016    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4017        """
4018        Checks whether this DataType matches one of the provided data types. Nested types or precision
4019        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4020
4021        Args:
4022            dtypes: the data types to compare this DataType to.
4023
4024        Returns:
4025            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4026        """
4027        for dtype in dtypes:
4028            other = DataType.build(dtype, copy=False, udt=True)
4029
4030            if (
4031                other.expressions
4032                or self.this == DataType.Type.USERDEFINED
4033                or other.this == DataType.Type.USERDEFINED
4034            ):
4035                matches = self == other
4036            else:
4037                matches = self.this == other.this
4038
4039            if matches:
4040                return True
4041        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NAME: 'NAME'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>}
INTEGER_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.UINT256: 'UINT256'>, <Type.INT128: 'INT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.UINT: 'UINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.FLOAT: 'FLOAT'>}
TEMPORAL_TYPES = {<Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIME: 'TIME'>, <Type.DATE: 'DATE'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMETZ: 'TIMETZ'>}
@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:
3970    @classmethod
3971    def build(
3972        cls,
3973        dtype: DATA_TYPE,
3974        dialect: DialectType = None,
3975        udt: bool = False,
3976        copy: bool = True,
3977        **kwargs,
3978    ) -> DataType:
3979        """
3980        Constructs a DataType object.
3981
3982        Args:
3983            dtype: the data type of interest.
3984            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3985            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3986                DataType, thus creating a user-defined type.
3987            copy: whether to copy the data type.
3988            kwargs: additional arguments to pass in the constructor of DataType.
3989
3990        Returns:
3991            The constructed DataType object.
3992        """
3993        from sqlglot import parse_one
3994
3995        if isinstance(dtype, str):
3996            if dtype.upper() == "UNKNOWN":
3997                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3998
3999            try:
4000                data_type_exp = parse_one(
4001                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4002                )
4003            except ParseError:
4004                if udt:
4005                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4006                raise
4007        elif isinstance(dtype, DataType.Type):
4008            data_type_exp = DataType(this=dtype)
4009        elif isinstance(dtype, DataType):
4010            return maybe_copy(dtype, copy)
4011        else:
4012            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4013
4014        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:
4016    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4017        """
4018        Checks whether this DataType matches one of the provided data types. Nested types or precision
4019        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4020
4021        Args:
4022            dtypes: the data types to compare this DataType to.
4023
4024        Returns:
4025            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4026        """
4027        for dtype in dtypes:
4028            other = DataType.build(dtype, copy=False, udt=True)
4029
4030            if (
4031                other.expressions
4032                or self.this == DataType.Type.USERDEFINED
4033                or other.this == DataType.Type.USERDEFINED
4034            ):
4035                matches = self == other
4036            else:
4037                matches = self.this == other.this
4038
4039            if matches:
4040                return True
4041        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):
3793    class Type(AutoName):
3794        ARRAY = auto()
3795        AGGREGATEFUNCTION = auto()
3796        SIMPLEAGGREGATEFUNCTION = auto()
3797        BIGDECIMAL = auto()
3798        BIGINT = auto()
3799        BIGSERIAL = auto()
3800        BINARY = auto()
3801        BIT = auto()
3802        BOOLEAN = auto()
3803        BPCHAR = auto()
3804        CHAR = auto()
3805        DATE = auto()
3806        DATE32 = auto()
3807        DATEMULTIRANGE = auto()
3808        DATERANGE = auto()
3809        DATETIME = auto()
3810        DATETIME64 = auto()
3811        DECIMAL = auto()
3812        DOUBLE = auto()
3813        ENUM = auto()
3814        ENUM8 = auto()
3815        ENUM16 = auto()
3816        FIXEDSTRING = auto()
3817        FLOAT = auto()
3818        GEOGRAPHY = auto()
3819        GEOMETRY = auto()
3820        HLLSKETCH = auto()
3821        HSTORE = auto()
3822        IMAGE = auto()
3823        INET = auto()
3824        INT = auto()
3825        INT128 = auto()
3826        INT256 = auto()
3827        INT4MULTIRANGE = auto()
3828        INT4RANGE = auto()
3829        INT8MULTIRANGE = auto()
3830        INT8RANGE = auto()
3831        INTERVAL = auto()
3832        IPADDRESS = auto()
3833        IPPREFIX = auto()
3834        IPV4 = auto()
3835        IPV6 = auto()
3836        JSON = auto()
3837        JSONB = auto()
3838        LONGBLOB = auto()
3839        LONGTEXT = auto()
3840        LOWCARDINALITY = auto()
3841        MAP = auto()
3842        MEDIUMBLOB = auto()
3843        MEDIUMINT = auto()
3844        MEDIUMTEXT = auto()
3845        MONEY = auto()
3846        NAME = auto()
3847        NCHAR = auto()
3848        NESTED = auto()
3849        NULL = auto()
3850        NULLABLE = auto()
3851        NUMMULTIRANGE = auto()
3852        NUMRANGE = auto()
3853        NVARCHAR = auto()
3854        OBJECT = auto()
3855        ROWVERSION = auto()
3856        SERIAL = auto()
3857        SET = auto()
3858        SMALLINT = auto()
3859        SMALLMONEY = auto()
3860        SMALLSERIAL = auto()
3861        STRUCT = auto()
3862        SUPER = auto()
3863        TEXT = auto()
3864        TINYBLOB = auto()
3865        TINYTEXT = auto()
3866        TIME = auto()
3867        TIMETZ = auto()
3868        TIMESTAMP = auto()
3869        TIMESTAMPLTZ = auto()
3870        TIMESTAMPTZ = auto()
3871        TIMESTAMP_S = auto()
3872        TIMESTAMP_MS = auto()
3873        TIMESTAMP_NS = auto()
3874        TINYINT = auto()
3875        TSMULTIRANGE = auto()
3876        TSRANGE = auto()
3877        TSTZMULTIRANGE = auto()
3878        TSTZRANGE = auto()
3879        UBIGINT = auto()
3880        UINT = auto()
3881        UINT128 = auto()
3882        UINT256 = auto()
3883        UMEDIUMINT = auto()
3884        UDECIMAL = auto()
3885        UNIQUEIDENTIFIER = auto()
3886        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3887        USERDEFINED = "USER-DEFINED"
3888        USMALLINT = auto()
3889        UTINYINT = auto()
3890        UUID = auto()
3891        VARBINARY = auto()
3892        VARCHAR = auto()
3893        VARIANT = auto()
3894        XML = auto()
3895        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):
4048class PseudoType(DataType):
4049    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4053class ObjectIdentifier(DataType):
4054    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4058class SubqueryPredicate(Predicate):
4059    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4062class All(SubqueryPredicate):
4063    pass
key = 'all'
class Any(SubqueryPredicate):
4066class Any(SubqueryPredicate):
4067    pass
key = 'any'
class Exists(SubqueryPredicate):
4070class Exists(SubqueryPredicate):
4071    pass
key = 'exists'
class Command(Expression):
4076class Command(Expression):
4077    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4080class Transaction(Expression):
4081    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4084class Commit(Expression):
4085    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4088class Rollback(Expression):
4089    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4092class AlterTable(Expression):
4093    arg_types = {
4094        "this": True,
4095        "actions": True,
4096        "exists": False,
4097        "only": False,
4098        "options": False,
4099    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
4102class AddConstraint(Expression):
4103    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4106class DropPartition(Expression):
4107    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
4111class Binary(Condition):
4112    arg_types = {"this": True, "expression": True}
4113
4114    @property
4115    def left(self) -> Expression:
4116        return self.this
4117
4118    @property
4119    def right(self) -> Expression:
4120        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4114    @property
4115    def left(self) -> Expression:
4116        return self.this
right: Expression
4118    @property
4119    def right(self) -> Expression:
4120        return self.expression
key = 'binary'
class Add(Binary):
4123class Add(Binary):
4124    pass
key = 'add'
class Connector(Binary):
4127class Connector(Binary):
4128    pass
key = 'connector'
class And(Connector):
4131class And(Connector):
4132    pass
key = 'and'
class Or(Connector):
4135class Or(Connector):
4136    pass
key = 'or'
class BitwiseAnd(Binary):
4139class BitwiseAnd(Binary):
4140    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4143class BitwiseLeftShift(Binary):
4144    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4147class BitwiseOr(Binary):
4148    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4151class BitwiseRightShift(Binary):
4152    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4155class BitwiseXor(Binary):
4156    pass
key = 'bitwisexor'
class Div(Binary):
4159class Div(Binary):
4160    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):
4163class Overlaps(Binary):
4164    pass
key = 'overlaps'
class Dot(Binary):
4167class Dot(Binary):
4168    @property
4169    def is_star(self) -> bool:
4170        return self.expression.is_star
4171
4172    @property
4173    def name(self) -> str:
4174        return self.expression.name
4175
4176    @property
4177    def output_name(self) -> str:
4178        return self.name
4179
4180    @classmethod
4181    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4182        """Build a Dot object with a sequence of expressions."""
4183        if len(expressions) < 2:
4184            raise ValueError("Dot requires >= 2 expressions.")
4185
4186        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4187
4188    @property
4189    def parts(self) -> t.List[Expression]:
4190        """Return the parts of a table / column in order catalog, db, table."""
4191        this, *parts = self.flatten()
4192
4193        parts.reverse()
4194
4195        for arg in ("this", "table", "db", "catalog"):
4196            part = this.args.get(arg)
4197
4198            if isinstance(part, Expression):
4199                parts.append(part)
4200
4201        parts.reverse()
4202        return parts
is_star: bool
4168    @property
4169    def is_star(self) -> bool:
4170        return self.expression.is_star

Checks whether an expression is a star.

name: str
4172    @property
4173    def name(self) -> str:
4174        return self.expression.name
output_name: str
4176    @property
4177    def output_name(self) -> str:
4178        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:
4180    @classmethod
4181    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4182        """Build a Dot object with a sequence of expressions."""
4183        if len(expressions) < 2:
4184            raise ValueError("Dot requires >= 2 expressions.")
4185
4186        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]
4188    @property
4189    def parts(self) -> t.List[Expression]:
4190        """Return the parts of a table / column in order catalog, db, table."""
4191        this, *parts = self.flatten()
4192
4193        parts.reverse()
4194
4195        for arg in ("this", "table", "db", "catalog"):
4196            part = this.args.get(arg)
4197
4198            if isinstance(part, Expression):
4199                parts.append(part)
4200
4201        parts.reverse()
4202        return parts

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

key = 'dot'
class DPipe(Binary):
4205class DPipe(Binary):
4206    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4209class EQ(Binary, Predicate):
4210    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4213class NullSafeEQ(Binary, Predicate):
4214    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4217class NullSafeNEQ(Binary, Predicate):
4218    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4222class PropertyEQ(Binary):
4223    pass
key = 'propertyeq'
class Distance(Binary):
4226class Distance(Binary):
4227    pass
key = 'distance'
class Escape(Binary):
4230class Escape(Binary):
4231    pass
key = 'escape'
class Glob(Binary, Predicate):
4234class Glob(Binary, Predicate):
4235    pass
key = 'glob'
class GT(Binary, Predicate):
4238class GT(Binary, Predicate):
4239    pass
key = 'gt'
class GTE(Binary, Predicate):
4242class GTE(Binary, Predicate):
4243    pass
key = 'gte'
class ILike(Binary, Predicate):
4246class ILike(Binary, Predicate):
4247    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4250class ILikeAny(Binary, Predicate):
4251    pass
key = 'ilikeany'
class IntDiv(Binary):
4254class IntDiv(Binary):
4255    pass
key = 'intdiv'
class Is(Binary, Predicate):
4258class Is(Binary, Predicate):
4259    pass
key = 'is'
class Kwarg(Binary):
4262class Kwarg(Binary):
4263    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4266class Like(Binary, Predicate):
4267    pass
key = 'like'
class LikeAny(Binary, Predicate):
4270class LikeAny(Binary, Predicate):
4271    pass
key = 'likeany'
class LT(Binary, Predicate):
4274class LT(Binary, Predicate):
4275    pass
key = 'lt'
class LTE(Binary, Predicate):
4278class LTE(Binary, Predicate):
4279    pass
key = 'lte'
class Mod(Binary):
4282class Mod(Binary):
4283    pass
key = 'mod'
class Mul(Binary):
4286class Mul(Binary):
4287    pass
key = 'mul'
class NEQ(Binary, Predicate):
4290class NEQ(Binary, Predicate):
4291    pass
key = 'neq'
class Operator(Binary):
4295class Operator(Binary):
4296    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4299class SimilarTo(Binary, Predicate):
4300    pass
key = 'similarto'
class Slice(Binary):
4303class Slice(Binary):
4304    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4307class Sub(Binary):
4308    pass
key = 'sub'
class Unary(Condition):
4313class Unary(Condition):
4314    pass
key = 'unary'
class BitwiseNot(Unary):
4317class BitwiseNot(Unary):
4318    pass
key = 'bitwisenot'
class Not(Unary):
4321class Not(Unary):
4322    pass
key = 'not'
class Paren(Unary):
4325class Paren(Unary):
4326    @property
4327    def output_name(self) -> str:
4328        return self.this.name
output_name: str
4326    @property
4327    def output_name(self) -> str:
4328        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):
4331class Neg(Unary):
4332    pass
key = 'neg'
class Alias(Expression):
4335class Alias(Expression):
4336    arg_types = {"this": True, "alias": False}
4337
4338    @property
4339    def output_name(self) -> str:
4340        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4338    @property
4339    def output_name(self) -> str:
4340        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):
4345class PivotAlias(Alias):
4346    pass
key = 'pivotalias'
class Aliases(Expression):
4349class Aliases(Expression):
4350    arg_types = {"this": True, "expressions": True}
4351
4352    @property
4353    def aliases(self):
4354        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4352    @property
4353    def aliases(self):
4354        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4358class AtIndex(Expression):
4359    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4362class AtTimeZone(Expression):
4363    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4366class FromTimeZone(Expression):
4367    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4370class Between(Predicate):
4371    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4374class Bracket(Condition):
4375    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4376    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4377
4378    @property
4379    def output_name(self) -> str:
4380        if len(self.expressions) == 1:
4381            return self.expressions[0].output_name
4382
4383        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4378    @property
4379    def output_name(self) -> str:
4380        if len(self.expressions) == 1:
4381            return self.expressions[0].output_name
4382
4383        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):
4386class Distinct(Expression):
4387    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4390class In(Predicate):
4391    arg_types = {
4392        "this": True,
4393        "expressions": False,
4394        "query": False,
4395        "unnest": False,
4396        "field": False,
4397        "is_global": False,
4398    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4402class ForIn(Expression):
4403    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4406class TimeUnit(Expression):
4407    """Automatically converts unit arg into a var."""
4408
4409    arg_types = {"unit": False}
4410
4411    UNABBREVIATED_UNIT_NAME = {
4412        "D": "DAY",
4413        "H": "HOUR",
4414        "M": "MINUTE",
4415        "MS": "MILLISECOND",
4416        "NS": "NANOSECOND",
4417        "Q": "QUARTER",
4418        "S": "SECOND",
4419        "US": "MICROSECOND",
4420        "W": "WEEK",
4421        "Y": "YEAR",
4422    }
4423
4424    VAR_LIKE = (Column, Literal, Var)
4425
4426    def __init__(self, **args):
4427        unit = args.get("unit")
4428        if isinstance(unit, self.VAR_LIKE):
4429            args["unit"] = Var(
4430                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4431            )
4432        elif isinstance(unit, Week):
4433            unit.set("this", Var(this=unit.this.name.upper()))
4434
4435        super().__init__(**args)
4436
4437    @property
4438    def unit(self) -> t.Optional[Var]:
4439        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4426    def __init__(self, **args):
4427        unit = args.get("unit")
4428        if isinstance(unit, self.VAR_LIKE):
4429            args["unit"] = Var(
4430                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4431            )
4432        elif isinstance(unit, Week):
4433            unit.set("this", Var(this=unit.this.name.upper()))
4434
4435        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: Optional[Var]
4437    @property
4438    def unit(self) -> t.Optional[Var]:
4439        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4442class IntervalOp(TimeUnit):
4443    arg_types = {"unit": True, "expression": True}
4444
4445    def interval(self):
4446        return Interval(
4447            this=self.expression.copy(),
4448            unit=self.unit.copy(),
4449        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4445    def interval(self):
4446        return Interval(
4447            this=self.expression.copy(),
4448            unit=self.unit.copy(),
4449        )
key = 'intervalop'
class IntervalSpan(DataType):
4455class IntervalSpan(DataType):
4456    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4459class Interval(TimeUnit):
4460    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4463class IgnoreNulls(Expression):
4464    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4467class RespectNulls(Expression):
4468    pass
key = 'respectnulls'
class HavingMax(Expression):
4472class HavingMax(Expression):
4473    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4477class Func(Condition):
4478    """
4479    The base class for all function expressions.
4480
4481    Attributes:
4482        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4483            treated as a variable length argument and the argument's value will be stored as a list.
4484        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4485            function expression. These values are used to map this node to a name during parsing as
4486            well as to provide the function's name during SQL string generation. By default the SQL
4487            name is set to the expression's class name transformed to snake case.
4488    """
4489
4490    is_var_len_args = False
4491
4492    @classmethod
4493    def from_arg_list(cls, args):
4494        if cls.is_var_len_args:
4495            all_arg_keys = list(cls.arg_types)
4496            # If this function supports variable length argument treat the last argument as such.
4497            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4498            num_non_var = len(non_var_len_arg_keys)
4499
4500            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4501            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4502        else:
4503            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4504
4505        return cls(**args_dict)
4506
4507    @classmethod
4508    def sql_names(cls):
4509        if cls is Func:
4510            raise NotImplementedError(
4511                "SQL name is only supported by concrete function implementations"
4512            )
4513        if "_sql_names" not in cls.__dict__:
4514            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4515        return cls._sql_names
4516
4517    @classmethod
4518    def sql_name(cls):
4519        return cls.sql_names()[0]
4520
4521    @classmethod
4522    def default_parser_mappings(cls):
4523        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):
4492    @classmethod
4493    def from_arg_list(cls, args):
4494        if cls.is_var_len_args:
4495            all_arg_keys = list(cls.arg_types)
4496            # If this function supports variable length argument treat the last argument as such.
4497            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4498            num_non_var = len(non_var_len_arg_keys)
4499
4500            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4501            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4502        else:
4503            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4504
4505        return cls(**args_dict)
@classmethod
def sql_names(cls):
4507    @classmethod
4508    def sql_names(cls):
4509        if cls is Func:
4510            raise NotImplementedError(
4511                "SQL name is only supported by concrete function implementations"
4512            )
4513        if "_sql_names" not in cls.__dict__:
4514            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4515        return cls._sql_names
@classmethod
def sql_name(cls):
4517    @classmethod
4518    def sql_name(cls):
4519        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4521    @classmethod
4522    def default_parser_mappings(cls):
4523        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4526class AggFunc(Func):
4527    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4530class ParameterizedAgg(AggFunc):
4531    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4534class Abs(Func):
4535    pass
key = 'abs'
class ArgMax(AggFunc):
4538class ArgMax(AggFunc):
4539    arg_types = {"this": True, "expression": True, "count": False}
4540    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4543class ArgMin(AggFunc):
4544    arg_types = {"this": True, "expression": True, "count": False}
4545    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4548class ApproxTopK(AggFunc):
4549    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4552class Flatten(Func):
4553    pass
key = 'flatten'
class Transform(Func):
4557class Transform(Func):
4558    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4561class Anonymous(Func):
4562    arg_types = {"this": True, "expressions": False}
4563    is_var_len_args = True
4564
4565    @property
4566    def name(self) -> str:
4567        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
4565    @property
4566    def name(self) -> str:
4567        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4570class AnonymousAggFunc(AggFunc):
4571    arg_types = {"this": True, "expressions": False}
4572    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4576class CombinedAggFunc(AnonymousAggFunc):
4577    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4580class CombinedParameterizedAgg(ParameterizedAgg):
4581    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):
4586class Hll(AggFunc):
4587    arg_types = {"this": True, "expressions": False}
4588    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4591class ApproxDistinct(AggFunc):
4592    arg_types = {"this": True, "accuracy": False}
4593    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4596class Array(Func):
4597    arg_types = {"expressions": False}
4598    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4602class ToArray(Func):
4603    pass
key = 'toarray'
class ToChar(Func):
4608class ToChar(Func):
4609    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4614class ToNumber(Func):
4615    arg_types = {
4616        "this": True,
4617        "format": False,
4618        "nlsparam": False,
4619        "precision": False,
4620        "scale": False,
4621    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4625class Convert(Func):
4626    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4629class GenerateSeries(Func):
4630    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):
4633class ArrayAgg(AggFunc):
4634    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4637class ArrayUniqueAgg(AggFunc):
4638    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4641class ArrayAll(Func):
4642    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4646class ArrayAny(Func):
4647    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4650class ArrayConcat(Func):
4651    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4652    arg_types = {"this": True, "expressions": False}
4653    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4656class ArrayContains(Binary, Func):
4657    pass
key = 'arraycontains'
class ArrayContained(Binary):
4660class ArrayContained(Binary):
4661    pass
key = 'arraycontained'
class ArrayFilter(Func):
4664class ArrayFilter(Func):
4665    arg_types = {"this": True, "expression": True}
4666    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4669class ArrayToString(Func):
4670    arg_types = {"this": True, "expression": True, "null": False}
4671    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4674class ArrayOverlaps(Binary, Func):
4675    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4678class ArraySize(Func):
4679    arg_types = {"this": True, "expression": False}
4680    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4683class ArraySort(Func):
4684    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4687class ArraySum(Func):
4688    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4691class ArrayUnionAgg(AggFunc):
4692    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4695class Avg(AggFunc):
4696    pass
key = 'avg'
class AnyValue(AggFunc):
4699class AnyValue(AggFunc):
4700    pass
key = 'anyvalue'
class Lag(AggFunc):
4703class Lag(AggFunc):
4704    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4707class Lead(AggFunc):
4708    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4713class First(AggFunc):
4714    pass
key = 'first'
class Last(AggFunc):
4717class Last(AggFunc):
4718    pass
key = 'last'
class FirstValue(AggFunc):
4721class FirstValue(AggFunc):
4722    pass
key = 'firstvalue'
class LastValue(AggFunc):
4725class LastValue(AggFunc):
4726    pass
key = 'lastvalue'
class NthValue(AggFunc):
4729class NthValue(AggFunc):
4730    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4733class Case(Func):
4734    arg_types = {"this": False, "ifs": True, "default": False}
4735
4736    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4737        instance = maybe_copy(self, copy)
4738        instance.append(
4739            "ifs",
4740            If(
4741                this=maybe_parse(condition, copy=copy, **opts),
4742                true=maybe_parse(then, copy=copy, **opts),
4743            ),
4744        )
4745        return instance
4746
4747    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4748        instance = maybe_copy(self, copy)
4749        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4750        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:
4736    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4737        instance = maybe_copy(self, copy)
4738        instance.append(
4739            "ifs",
4740            If(
4741                this=maybe_parse(condition, copy=copy, **opts),
4742                true=maybe_parse(then, copy=copy, **opts),
4743            ),
4744        )
4745        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4747    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4748        instance = maybe_copy(self, copy)
4749        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4750        return instance
key = 'case'
class Cast(Func):
4753class Cast(Func):
4754    arg_types = {
4755        "this": True,
4756        "to": True,
4757        "format": False,
4758        "safe": False,
4759        "action": False,
4760    }
4761
4762    @property
4763    def name(self) -> str:
4764        return self.this.name
4765
4766    @property
4767    def to(self) -> DataType:
4768        return self.args["to"]
4769
4770    @property
4771    def output_name(self) -> str:
4772        return self.name
4773
4774    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4775        """
4776        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4777        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4778        array<int> != array<float>.
4779
4780        Args:
4781            dtypes: the data types to compare this Cast's DataType to.
4782
4783        Returns:
4784            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4785        """
4786        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4762    @property
4763    def name(self) -> str:
4764        return self.this.name
to: DataType
4766    @property
4767    def to(self) -> DataType:
4768        return self.args["to"]
output_name: str
4770    @property
4771    def output_name(self) -> str:
4772        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:
4774    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4775        """
4776        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4777        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4778        array<int> != array<float>.
4779
4780        Args:
4781            dtypes: the data types to compare this Cast's DataType to.
4782
4783        Returns:
4784            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4785        """
4786        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):
4789class TryCast(Cast):
4790    pass
key = 'trycast'
class CastToStrType(Func):
4793class CastToStrType(Func):
4794    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4797class Collate(Binary, Func):
4798    pass
key = 'collate'
class Ceil(Func):
4801class Ceil(Func):
4802    arg_types = {"this": True, "decimals": False}
4803    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4806class Coalesce(Func):
4807    arg_types = {"this": True, "expressions": False}
4808    is_var_len_args = True
4809    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4812class Chr(Func):
4813    arg_types = {"this": True, "charset": False, "expressions": False}
4814    is_var_len_args = True
4815    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4818class Concat(Func):
4819    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4820    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4823class ConcatWs(Concat):
4824    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4828class ConnectByRoot(Func):
4829    pass
key = 'connectbyroot'
class Count(AggFunc):
4832class Count(AggFunc):
4833    arg_types = {"this": False, "expressions": False}
4834    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4837class CountIf(AggFunc):
4838    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4842class Cbrt(Func):
4843    pass
key = 'cbrt'
class CurrentDate(Func):
4846class CurrentDate(Func):
4847    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4850class CurrentDatetime(Func):
4851    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4854class CurrentTime(Func):
4855    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4858class CurrentTimestamp(Func):
4859    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4862class CurrentUser(Func):
4863    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4866class DateAdd(Func, IntervalOp):
4867    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4870class DateSub(Func, IntervalOp):
4871    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4874class DateDiff(Func, TimeUnit):
4875    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4876    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4879class DateTrunc(Func):
4880    arg_types = {"unit": True, "this": True, "zone": False}
4881
4882    def __init__(self, **args):
4883        unit = args.get("unit")
4884        if isinstance(unit, TimeUnit.VAR_LIKE):
4885            args["unit"] = Literal.string(
4886                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4887            )
4888        elif isinstance(unit, Week):
4889            unit.set("this", Literal.string(unit.this.name.upper()))
4890
4891        super().__init__(**args)
4892
4893    @property
4894    def unit(self) -> Expression:
4895        return self.args["unit"]
DateTrunc(**args)
4882    def __init__(self, **args):
4883        unit = args.get("unit")
4884        if isinstance(unit, TimeUnit.VAR_LIKE):
4885            args["unit"] = Literal.string(
4886                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4887            )
4888        elif isinstance(unit, Week):
4889            unit.set("this", Literal.string(unit.this.name.upper()))
4890
4891        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4893    @property
4894    def unit(self) -> Expression:
4895        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4898class DatetimeAdd(Func, IntervalOp):
4899    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4902class DatetimeSub(Func, IntervalOp):
4903    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4906class DatetimeDiff(Func, TimeUnit):
4907    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4910class DatetimeTrunc(Func, TimeUnit):
4911    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4914class DayOfWeek(Func):
4915    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4918class DayOfMonth(Func):
4919    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4922class DayOfYear(Func):
4923    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4926class ToDays(Func):
4927    pass
key = 'todays'
class WeekOfYear(Func):
4930class WeekOfYear(Func):
4931    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4934class MonthsBetween(Func):
4935    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4938class LastDay(Func, TimeUnit):
4939    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4940    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4943class Extract(Func):
4944    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4947class Timestamp(Func):
4948    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4951class TimestampAdd(Func, TimeUnit):
4952    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4955class TimestampSub(Func, TimeUnit):
4956    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4959class TimestampDiff(Func, TimeUnit):
4960    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4961    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4964class TimestampTrunc(Func, TimeUnit):
4965    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4968class TimeAdd(Func, TimeUnit):
4969    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4972class TimeSub(Func, TimeUnit):
4973    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4976class TimeDiff(Func, TimeUnit):
4977    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4980class TimeTrunc(Func, TimeUnit):
4981    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4984class DateFromParts(Func):
4985    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4986    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4989class TimeFromParts(Func):
4990    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4991    arg_types = {
4992        "hour": True,
4993        "min": True,
4994        "sec": True,
4995        "nano": False,
4996        "fractions": False,
4997        "precision": False,
4998    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5001class DateStrToDate(Func):
5002    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5005class DateToDateStr(Func):
5006    pass
key = 'datetodatestr'
class DateToDi(Func):
5009class DateToDi(Func):
5010    pass
key = 'datetodi'
class Date(Func):
5014class Date(Func):
5015    arg_types = {"this": False, "zone": False, "expressions": False}
5016    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5019class Day(Func):
5020    pass
key = 'day'
class Decode(Func):
5023class Decode(Func):
5024    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5027class DiToDate(Func):
5028    pass
key = 'ditodate'
class Encode(Func):
5031class Encode(Func):
5032    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5035class Exp(Func):
5036    pass
key = 'exp'
class Explode(Func):
5040class Explode(Func):
5041    arg_types = {"this": True, "expressions": False}
5042    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5045class ExplodeOuter(Explode):
5046    pass
key = 'explodeouter'
class Posexplode(Explode):
5049class Posexplode(Explode):
5050    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5053class PosexplodeOuter(Posexplode, ExplodeOuter):
5054    pass
key = 'posexplodeouter'
class Floor(Func):
5057class Floor(Func):
5058    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5061class FromBase64(Func):
5062    pass
key = 'frombase64'
class ToBase64(Func):
5065class ToBase64(Func):
5066    pass
key = 'tobase64'
class GenerateDateArray(Func):
5069class GenerateDateArray(Func):
5070    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5073class Greatest(Func):
5074    arg_types = {"this": True, "expressions": False}
5075    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5078class GroupConcat(AggFunc):
5079    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5082class Hex(Func):
5083    pass
key = 'hex'
class Xor(Connector, Func):
5086class Xor(Connector, Func):
5087    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5090class If(Func):
5091    arg_types = {"this": True, "true": True, "false": False}
5092    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5095class Nullif(Func):
5096    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5099class Initcap(Func):
5100    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5103class IsNan(Func):
5104    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5107class IsInf(Func):
5108    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5111class JSONPath(Expression):
5112    arg_types = {"expressions": True}
5113
5114    @property
5115    def output_name(self) -> str:
5116        last_segment = self.expressions[-1].this
5117        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5114    @property
5115    def output_name(self) -> str:
5116        last_segment = self.expressions[-1].this
5117        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):
5120class JSONPathPart(Expression):
5121    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5124class JSONPathFilter(JSONPathPart):
5125    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5128class JSONPathKey(JSONPathPart):
5129    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5132class JSONPathRecursive(JSONPathPart):
5133    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5136class JSONPathRoot(JSONPathPart):
5137    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5140class JSONPathScript(JSONPathPart):
5141    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5144class JSONPathSlice(JSONPathPart):
5145    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5148class JSONPathSelector(JSONPathPart):
5149    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5152class JSONPathSubscript(JSONPathPart):
5153    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5156class JSONPathUnion(JSONPathPart):
5157    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5160class JSONPathWildcard(JSONPathPart):
5161    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5164class FormatJson(Expression):
5165    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5168class JSONKeyValue(Expression):
5169    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5172class JSONObject(Func):
5173    arg_types = {
5174        "expressions": False,
5175        "null_handling": False,
5176        "unique_keys": False,
5177        "return_type": False,
5178        "encoding": False,
5179    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5182class JSONObjectAgg(AggFunc):
5183    arg_types = {
5184        "expressions": False,
5185        "null_handling": False,
5186        "unique_keys": False,
5187        "return_type": False,
5188        "encoding": False,
5189    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5193class JSONArray(Func):
5194    arg_types = {
5195        "expressions": True,
5196        "null_handling": False,
5197        "return_type": False,
5198        "strict": False,
5199    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5203class JSONArrayAgg(Func):
5204    arg_types = {
5205        "this": True,
5206        "order": False,
5207        "null_handling": False,
5208        "return_type": False,
5209        "strict": False,
5210    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5215class JSONColumnDef(Expression):
5216    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):
5219class JSONSchema(Expression):
5220    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5224class JSONTable(Func):
5225    arg_types = {
5226        "this": True,
5227        "schema": True,
5228        "path": False,
5229        "error_handling": False,
5230        "empty_handling": False,
5231    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5234class OpenJSONColumnDef(Expression):
5235    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):
5238class OpenJSON(Func):
5239    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5242class JSONBContains(Binary):
5243    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5246class JSONExtract(Binary, Func):
5247    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5248    _sql_names = ["JSON_EXTRACT"]
5249    is_var_len_args = True
5250
5251    @property
5252    def output_name(self) -> str:
5253        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
5251    @property
5252    def output_name(self) -> str:
5253        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):
5256class JSONExtractScalar(Binary, Func):
5257    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5258    _sql_names = ["JSON_EXTRACT_SCALAR"]
5259    is_var_len_args = True
5260
5261    @property
5262    def output_name(self) -> str:
5263        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
5261    @property
5262    def output_name(self) -> str:
5263        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):
5266class JSONBExtract(Binary, Func):
5267    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5270class JSONBExtractScalar(Binary, Func):
5271    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5274class JSONFormat(Func):
5275    arg_types = {"this": False, "options": False}
5276    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5280class JSONArrayContains(Binary, Predicate, Func):
5281    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5284class ParseJSON(Func):
5285    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5286    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5287    arg_types = {"this": True, "expressions": False}
5288    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5291class Least(Func):
5292    arg_types = {"this": True, "expressions": False}
5293    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5296class Left(Func):
5297    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5304class Length(Func):
5305    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5308class Levenshtein(Func):
5309    arg_types = {
5310        "this": True,
5311        "expression": False,
5312        "ins_cost": False,
5313        "del_cost": False,
5314        "sub_cost": False,
5315    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5318class Ln(Func):
5319    pass
key = 'ln'
class Log(Func):
5322class Log(Func):
5323    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5326class LogicalOr(AggFunc):
5327    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5330class LogicalAnd(AggFunc):
5331    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5334class Lower(Func):
5335    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5338class Map(Func):
5339    arg_types = {"keys": False, "values": False}
5340
5341    @property
5342    def keys(self) -> t.List[Expression]:
5343        keys = self.args.get("keys")
5344        return keys.expressions if keys else []
5345
5346    @property
5347    def values(self) -> t.List[Expression]:
5348        values = self.args.get("values")
5349        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5341    @property
5342    def keys(self) -> t.List[Expression]:
5343        keys = self.args.get("keys")
5344        return keys.expressions if keys else []
values: List[Expression]
5346    @property
5347    def values(self) -> t.List[Expression]:
5348        values = self.args.get("values")
5349        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5352class MapFromEntries(Func):
5353    pass
key = 'mapfromentries'
class StarMap(Func):
5356class StarMap(Func):
5357    pass
key = 'starmap'
class VarMap(Func):
5360class VarMap(Func):
5361    arg_types = {"keys": True, "values": True}
5362    is_var_len_args = True
5363
5364    @property
5365    def keys(self) -> t.List[Expression]:
5366        return self.args["keys"].expressions
5367
5368    @property
5369    def values(self) -> t.List[Expression]:
5370        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5364    @property
5365    def keys(self) -> t.List[Expression]:
5366        return self.args["keys"].expressions
values: List[Expression]
5368    @property
5369    def values(self) -> t.List[Expression]:
5370        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5374class MatchAgainst(Func):
5375    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5378class Max(AggFunc):
5379    arg_types = {"this": True, "expressions": False}
5380    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5383class MD5(Func):
5384    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5388class MD5Digest(Func):
5389    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5392class Min(AggFunc):
5393    arg_types = {"this": True, "expressions": False}
5394    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5397class Month(Func):
5398    pass
key = 'month'
class AddMonths(Func):
5401class AddMonths(Func):
5402    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5405class Nvl2(Func):
5406    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5410class Predict(Func):
5411    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5414class Pow(Binary, Func):
5415    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5418class PercentileCont(AggFunc):
5419    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5422class PercentileDisc(AggFunc):
5423    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5426class Quantile(AggFunc):
5427    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5430class ApproxQuantile(Quantile):
5431    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Rand(Func):
5434class Rand(Func):
5435    _sql_names = ["RAND", "RANDOM"]
5436    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5439class Randn(Func):
5440    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5443class RangeN(Func):
5444    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5447class ReadCSV(Func):
5448    _sql_names = ["READ_CSV"]
5449    is_var_len_args = True
5450    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5453class Reduce(Func):
5454    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):
5457class RegexpExtract(Func):
5458    arg_types = {
5459        "this": True,
5460        "expression": True,
5461        "position": False,
5462        "occurrence": False,
5463        "parameters": False,
5464        "group": False,
5465    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5468class RegexpReplace(Func):
5469    arg_types = {
5470        "this": True,
5471        "expression": True,
5472        "replacement": False,
5473        "position": False,
5474        "occurrence": False,
5475        "parameters": False,
5476        "modifiers": False,
5477    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5480class RegexpLike(Binary, Func):
5481    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5484class RegexpILike(Binary, Func):
5485    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5490class RegexpSplit(Func):
5491    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5494class Repeat(Func):
5495    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5500class Round(Func):
5501    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5504class RowNumber(Func):
5505    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5508class SafeDivide(Func):
5509    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5512class SHA(Func):
5513    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5516class SHA2(Func):
5517    _sql_names = ["SHA2"]
5518    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5521class Sign(Func):
5522    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5525class SortArray(Func):
5526    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5529class Split(Func):
5530    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5535class Substring(Func):
5536    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5539class StandardHash(Func):
5540    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5543class StartsWith(Func):
5544    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5545    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5548class StrPosition(Func):
5549    arg_types = {
5550        "this": True,
5551        "substr": True,
5552        "position": False,
5553        "instance": False,
5554    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5557class StrToDate(Func):
5558    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5561class StrToTime(Func):
5562    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5567class StrToUnix(Func):
5568    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5573class StrToMap(Func):
5574    arg_types = {
5575        "this": True,
5576        "pair_delim": False,
5577        "key_value_delim": False,
5578        "duplicate_resolution_callback": False,
5579    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5582class NumberToStr(Func):
5583    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5586class FromBase(Func):
5587    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5590class Struct(Func):
5591    arg_types = {"expressions": False}
5592    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5595class StructExtract(Func):
5596    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5601class Stuff(Func):
5602    _sql_names = ["STUFF", "INSERT"]
5603    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):
5606class Sum(AggFunc):
5607    pass
key = 'sum'
class Sqrt(Func):
5610class Sqrt(Func):
5611    pass
key = 'sqrt'
class Stddev(AggFunc):
5614class Stddev(AggFunc):
5615    pass
key = 'stddev'
class StddevPop(AggFunc):
5618class StddevPop(AggFunc):
5619    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5622class StddevSamp(AggFunc):
5623    pass
key = 'stddevsamp'
class TimeToStr(Func):
5626class TimeToStr(Func):
5627    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5630class TimeToTimeStr(Func):
5631    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5634class TimeToUnix(Func):
5635    pass
key = 'timetounix'
class TimeStrToDate(Func):
5638class TimeStrToDate(Func):
5639    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5642class TimeStrToTime(Func):
5643    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5646class TimeStrToUnix(Func):
5647    pass
key = 'timestrtounix'
class Trim(Func):
5650class Trim(Func):
5651    arg_types = {
5652        "this": True,
5653        "expression": False,
5654        "position": False,
5655        "collation": False,
5656    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5659class TsOrDsAdd(Func, TimeUnit):
5660    # return_type is used to correctly cast the arguments of this expression when transpiling it
5661    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5662
5663    @property
5664    def return_type(self) -> DataType:
5665        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
5663    @property
5664    def return_type(self) -> DataType:
5665        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5668class TsOrDsDiff(Func, TimeUnit):
5669    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5672class TsOrDsToDateStr(Func):
5673    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5676class TsOrDsToDate(Func):
5677    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5680class TsOrDsToTime(Func):
5681    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5684class TsOrDiToDi(Func):
5685    pass
key = 'tsorditodi'
class Unhex(Func):
5688class Unhex(Func):
5689    pass
key = 'unhex'
class UnixDate(Func):
5693class UnixDate(Func):
5694    pass
key = 'unixdate'
class UnixToStr(Func):
5697class UnixToStr(Func):
5698    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5703class UnixToTime(Func):
5704    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5705
5706    SECONDS = Literal.number(0)
5707    DECIS = Literal.number(1)
5708    CENTIS = Literal.number(2)
5709    MILLIS = Literal.number(3)
5710    DECIMILLIS = Literal.number(4)
5711    CENTIMILLIS = Literal.number(5)
5712    MICROS = Literal.number(6)
5713    DECIMICROS = Literal.number(7)
5714    CENTIMICROS = Literal.number(8)
5715    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': 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):
5718class UnixToTimeStr(Func):
5719    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5722class TimestampFromParts(Func):
5723    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5724    arg_types = {
5725        "year": True,
5726        "month": True,
5727        "day": True,
5728        "hour": True,
5729        "min": True,
5730        "sec": True,
5731        "nano": False,
5732        "zone": False,
5733        "milli": False,
5734    }
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):
5737class Upper(Func):
5738    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5741class Variance(AggFunc):
5742    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5745class VariancePop(AggFunc):
5746    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5749class Week(Func):
5750    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5753class XMLTable(Func):
5754    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):
5757class Year(Func):
5758    pass
key = 'year'
class Use(Expression):
5761class Use(Expression):
5762    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5765class Merge(Expression):
5766    arg_types = {
5767        "this": True,
5768        "using": True,
5769        "on": True,
5770        "expressions": True,
5771        "with": False,
5772    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5775class When(Func):
5776    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):
5781class NextValueFor(Func):
5782    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 'Count'>, <class 'CountIf'>, <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 '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 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <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'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, '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'>, '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_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'>, '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'>]
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:
5820def maybe_parse(
5821    sql_or_expression: ExpOrStr,
5822    *,
5823    into: t.Optional[IntoType] = None,
5824    dialect: DialectType = None,
5825    prefix: t.Optional[str] = None,
5826    copy: bool = False,
5827    **opts,
5828) -> Expression:
5829    """Gracefully handle a possible string or expression.
5830
5831    Example:
5832        >>> maybe_parse("1")
5833        Literal(this=1, is_string=False)
5834        >>> maybe_parse(to_identifier("x"))
5835        Identifier(this=x, quoted=False)
5836
5837    Args:
5838        sql_or_expression: the SQL code string or an expression
5839        into: the SQLGlot Expression to parse into
5840        dialect: the dialect used to parse the input expressions (in the case that an
5841            input expression is a SQL string).
5842        prefix: a string to prefix the sql with before it gets parsed
5843            (automatically includes a space)
5844        copy: whether to copy the expression.
5845        **opts: other options to use to parse the input expressions (again, in the case
5846            that an input expression is a SQL string).
5847
5848    Returns:
5849        Expression: the parsed or given expression.
5850    """
5851    if isinstance(sql_or_expression, Expression):
5852        if copy:
5853            return sql_or_expression.copy()
5854        return sql_or_expression
5855
5856    if sql_or_expression is None:
5857        raise ParseError("SQL cannot be None")
5858
5859    import sqlglot
5860
5861    sql = str(sql_or_expression)
5862    if prefix:
5863        sql = f"{prefix} {sql}"
5864
5865    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):
5876def maybe_copy(instance, copy=True):
5877    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:
6091def union(
6092    left: ExpOrStr,
6093    right: ExpOrStr,
6094    distinct: bool = True,
6095    dialect: DialectType = None,
6096    copy: bool = True,
6097    **opts,
6098) -> Union:
6099    """
6100    Initializes a syntax tree from one UNION expression.
6101
6102    Example:
6103        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6104        'SELECT * FROM foo UNION SELECT * FROM bla'
6105
6106    Args:
6107        left: the SQL code string corresponding to the left-hand side.
6108            If an `Expression` instance is passed, it will be used as-is.
6109        right: the SQL code string corresponding to the right-hand side.
6110            If an `Expression` instance is passed, it will be used as-is.
6111        distinct: set the DISTINCT flag if and only if this is true.
6112        dialect: the dialect used to parse the input expression.
6113        copy: whether to copy the expression.
6114        opts: other options to use to parse the input expressions.
6115
6116    Returns:
6117        The new Union instance.
6118    """
6119    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6120    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6121
6122    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:
6125def intersect(
6126    left: ExpOrStr,
6127    right: ExpOrStr,
6128    distinct: bool = True,
6129    dialect: DialectType = None,
6130    copy: bool = True,
6131    **opts,
6132) -> Intersect:
6133    """
6134    Initializes a syntax tree from one INTERSECT expression.
6135
6136    Example:
6137        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6138        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6139
6140    Args:
6141        left: the SQL code string corresponding to the left-hand side.
6142            If an `Expression` instance is passed, it will be used as-is.
6143        right: the SQL code string corresponding to the right-hand side.
6144            If an `Expression` instance is passed, it will be used as-is.
6145        distinct: set the DISTINCT flag if and only if this is true.
6146        dialect: the dialect used to parse the input expression.
6147        copy: whether to copy the expression.
6148        opts: other options to use to parse the input expressions.
6149
6150    Returns:
6151        The new Intersect instance.
6152    """
6153    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6154    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6155
6156    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:
6159def except_(
6160    left: ExpOrStr,
6161    right: ExpOrStr,
6162    distinct: bool = True,
6163    dialect: DialectType = None,
6164    copy: bool = True,
6165    **opts,
6166) -> Except:
6167    """
6168    Initializes a syntax tree from one EXCEPT expression.
6169
6170    Example:
6171        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6172        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6173
6174    Args:
6175        left: the SQL code string corresponding to the left-hand side.
6176            If an `Expression` instance is passed, it will be used as-is.
6177        right: the SQL code string corresponding to the right-hand side.
6178            If an `Expression` instance is passed, it will be used as-is.
6179        distinct: set the DISTINCT flag if and only if this is true.
6180        dialect: the dialect used to parse the input expression.
6181        copy: whether to copy the expression.
6182        opts: other options to use to parse the input expressions.
6183
6184    Returns:
6185        The new Except instance.
6186    """
6187    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6188    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6189
6190    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:
6193def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6194    """
6195    Initializes a syntax tree from one or multiple SELECT expressions.
6196
6197    Example:
6198        >>> select("col1", "col2").from_("tbl").sql()
6199        'SELECT col1, col2 FROM tbl'
6200
6201    Args:
6202        *expressions: the SQL code string to parse as the expressions of a
6203            SELECT statement. If an Expression instance is passed, this is used as-is.
6204        dialect: the dialect used to parse the input expressions (in the case that an
6205            input expression is a SQL string).
6206        **opts: other options to use to parse the input expressions (again, in the case
6207            that an input expression is a SQL string).
6208
6209    Returns:
6210        Select: the syntax tree for the SELECT statement.
6211    """
6212    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:
6215def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6216    """
6217    Initializes a syntax tree from a FROM expression.
6218
6219    Example:
6220        >>> from_("tbl").select("col1", "col2").sql()
6221        'SELECT col1, col2 FROM tbl'
6222
6223    Args:
6224        *expression: the SQL code string to parse as the FROM expressions of a
6225            SELECT statement. If an Expression instance is passed, this is used as-is.
6226        dialect: the dialect used to parse the input expression (in the case that the
6227            input expression is a SQL string).
6228        **opts: other options to use to parse the input expressions (again, in the case
6229            that the input expression is a SQL string).
6230
6231    Returns:
6232        Select: the syntax tree for the SELECT statement.
6233    """
6234    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:
6237def update(
6238    table: str | Table,
6239    properties: dict,
6240    where: t.Optional[ExpOrStr] = None,
6241    from_: t.Optional[ExpOrStr] = None,
6242    dialect: DialectType = None,
6243    **opts,
6244) -> Update:
6245    """
6246    Creates an update statement.
6247
6248    Example:
6249        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6250        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6251
6252    Args:
6253        *properties: dictionary of properties to set which are
6254            auto converted to sql objects eg None -> NULL
6255        where: sql conditional parsed into a WHERE statement
6256        from_: sql statement parsed into a FROM statement
6257        dialect: the dialect used to parse the input expressions.
6258        **opts: other options to use to parse the input expressions.
6259
6260    Returns:
6261        Update: the syntax tree for the UPDATE statement.
6262    """
6263    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6264    update_expr.set(
6265        "expressions",
6266        [
6267            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6268            for k, v in properties.items()
6269        ],
6270    )
6271    if from_:
6272        update_expr.set(
6273            "from",
6274            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6275        )
6276    if isinstance(where, Condition):
6277        where = Where(this=where)
6278    if where:
6279        update_expr.set(
6280            "where",
6281            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6282        )
6283    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:
6286def delete(
6287    table: ExpOrStr,
6288    where: t.Optional[ExpOrStr] = None,
6289    returning: t.Optional[ExpOrStr] = None,
6290    dialect: DialectType = None,
6291    **opts,
6292) -> Delete:
6293    """
6294    Builds a delete statement.
6295
6296    Example:
6297        >>> delete("my_table", where="id > 1").sql()
6298        'DELETE FROM my_table WHERE id > 1'
6299
6300    Args:
6301        where: sql conditional parsed into a WHERE statement
6302        returning: sql conditional parsed into a RETURNING statement
6303        dialect: the dialect used to parse the input expressions.
6304        **opts: other options to use to parse the input expressions.
6305
6306    Returns:
6307        Delete: the syntax tree for the DELETE statement.
6308    """
6309    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6310    if where:
6311        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6312    if returning:
6313        delete_expr = t.cast(
6314            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6315        )
6316    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:
6319def insert(
6320    expression: ExpOrStr,
6321    into: ExpOrStr,
6322    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6323    overwrite: t.Optional[bool] = None,
6324    returning: t.Optional[ExpOrStr] = None,
6325    dialect: DialectType = None,
6326    copy: bool = True,
6327    **opts,
6328) -> Insert:
6329    """
6330    Builds an INSERT statement.
6331
6332    Example:
6333        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6334        'INSERT INTO tbl VALUES (1, 2, 3)'
6335
6336    Args:
6337        expression: the sql string or expression of the INSERT statement
6338        into: the tbl to insert data to.
6339        columns: optionally the table's column names.
6340        overwrite: whether to INSERT OVERWRITE or not.
6341        returning: sql conditional parsed into a RETURNING statement
6342        dialect: the dialect used to parse the input expressions.
6343        copy: whether to copy the expression.
6344        **opts: other options to use to parse the input expressions.
6345
6346    Returns:
6347        Insert: the syntax tree for the INSERT statement.
6348    """
6349    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6350    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6351
6352    if columns:
6353        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6354
6355    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6356
6357    if returning:
6358        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6359
6360    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:
6363def condition(
6364    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6365) -> Condition:
6366    """
6367    Initialize a logical condition expression.
6368
6369    Example:
6370        >>> condition("x=1").sql()
6371        'x = 1'
6372
6373        This is helpful for composing larger logical syntax trees:
6374        >>> where = condition("x=1")
6375        >>> where = where.and_("y=1")
6376        >>> Select().from_("tbl").select("*").where(where).sql()
6377        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6378
6379    Args:
6380        *expression: the SQL code string to parse.
6381            If an Expression instance is passed, this is used as-is.
6382        dialect: the dialect used to parse the input expression (in the case that the
6383            input expression is a SQL string).
6384        copy: Whether to copy `expression` (only applies to expressions).
6385        **opts: other options to use to parse the input expressions (again, in the case
6386            that the input expression is a SQL string).
6387
6388    Returns:
6389        The new Condition instance
6390    """
6391    return maybe_parse(
6392        expression,
6393        into=Condition,
6394        dialect=dialect,
6395        copy=copy,
6396        **opts,
6397    )

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:
6400def and_(
6401    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6402) -> Condition:
6403    """
6404    Combine multiple conditions with an AND logical operator.
6405
6406    Example:
6407        >>> and_("x=1", and_("y=1", "z=1")).sql()
6408        'x = 1 AND (y = 1 AND z = 1)'
6409
6410    Args:
6411        *expressions: the SQL code strings to parse.
6412            If an Expression instance is passed, this is used as-is.
6413        dialect: the dialect used to parse the input expression.
6414        copy: whether to copy `expressions` (only applies to Expressions).
6415        **opts: other options to use to parse the input expressions.
6416
6417    Returns:
6418        And: the new condition
6419    """
6420    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:
6423def or_(
6424    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6425) -> Condition:
6426    """
6427    Combine multiple conditions with an OR logical operator.
6428
6429    Example:
6430        >>> or_("x=1", or_("y=1", "z=1")).sql()
6431        'x = 1 OR (y = 1 OR z = 1)'
6432
6433    Args:
6434        *expressions: the SQL code strings to parse.
6435            If an Expression instance is passed, this is used as-is.
6436        dialect: the dialect used to parse the input expression.
6437        copy: whether to copy `expressions` (only applies to Expressions).
6438        **opts: other options to use to parse the input expressions.
6439
6440    Returns:
6441        Or: the new condition
6442    """
6443    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:
6446def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6447    """
6448    Wrap a condition with a NOT operator.
6449
6450    Example:
6451        >>> not_("this_suit='black'").sql()
6452        "NOT this_suit = 'black'"
6453
6454    Args:
6455        expression: the SQL code string to parse.
6456            If an Expression instance is passed, this is used as-is.
6457        dialect: the dialect used to parse the input expression.
6458        copy: whether to copy the expression or not.
6459        **opts: other options to use to parse the input expressions.
6460
6461    Returns:
6462        The new condition.
6463    """
6464    this = condition(
6465        expression,
6466        dialect=dialect,
6467        copy=copy,
6468        **opts,
6469    )
6470    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:
6473def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6474    """
6475    Wrap an expression in parentheses.
6476
6477    Example:
6478        >>> paren("5 + 3").sql()
6479        '(5 + 3)'
6480
6481    Args:
6482        expression: the SQL code string to parse.
6483            If an Expression instance is passed, this is used as-is.
6484        copy: whether to copy the expression or not.
6485
6486    Returns:
6487        The wrapped expression.
6488    """
6489    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):
6505def to_identifier(name, quoted=None, copy=True):
6506    """Builds an identifier.
6507
6508    Args:
6509        name: The name to turn into an identifier.
6510        quoted: Whether to force quote the identifier.
6511        copy: Whether to copy name if it's an Identifier.
6512
6513    Returns:
6514        The identifier ast node.
6515    """
6516
6517    if name is None:
6518        return None
6519
6520    if isinstance(name, Identifier):
6521        identifier = maybe_copy(name, copy)
6522    elif isinstance(name, str):
6523        identifier = Identifier(
6524            this=name,
6525            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6526        )
6527    else:
6528        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6529    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:
6532def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6533    """
6534    Parses a given string into an identifier.
6535
6536    Args:
6537        name: The name to parse into an identifier.
6538        dialect: The dialect to parse against.
6539
6540    Returns:
6541        The identifier ast node.
6542    """
6543    try:
6544        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6545    except ParseError:
6546        expression = to_identifier(name)
6547
6548    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:
6554def to_interval(interval: str | Literal) -> Interval:
6555    """Builds an interval expression from a string like '1 day' or '5 months'."""
6556    if isinstance(interval, Literal):
6557        if not interval.is_string:
6558            raise ValueError("Invalid interval string.")
6559
6560        interval = interval.this
6561
6562    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6563
6564    if not interval_parts:
6565        raise ValueError("Invalid interval string.")
6566
6567    return Interval(
6568        this=Literal.string(interval_parts.group(1)),
6569        unit=Var(this=interval_parts.group(2).upper()),
6570    )

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: Union[str, Table, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Optional[Table]:
6581def to_table(
6582    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6583) -> t.Optional[Table]:
6584    """
6585    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6586    If a table is passed in then that table is returned.
6587
6588    Args:
6589        sql_path: a `[catalog].[schema].[table]` string.
6590        dialect: the source dialect according to which the table name will be parsed.
6591        copy: Whether to copy a table if it is passed in.
6592        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6593
6594    Returns:
6595        A table expression.
6596    """
6597    if sql_path is None or isinstance(sql_path, Table):
6598        return maybe_copy(sql_path, copy=copy)
6599    if not isinstance(sql_path, str):
6600        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6601
6602    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6603    if table:
6604        for k, v in kwargs.items():
6605            table.set(k, v)
6606
6607    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, **kwargs) -> Column:
6610def to_column(sql_path: str | Column, **kwargs) -> Column:
6611    """
6612    Create a column from a `[table].[column]` sql path. Schema is optional.
6613
6614    If a column is passed in then that column is returned.
6615
6616    Args:
6617        sql_path: `[table].[column]` string
6618    Returns:
6619        Table: A column expression
6620    """
6621    if sql_path is None or isinstance(sql_path, Column):
6622        return sql_path
6623    if not isinstance(sql_path, str):
6624        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6625    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore

Create a column from a [table].[column] sql path. Schema is optional.

If a column is passed in then that column is returned.

Arguments:
  • sql_path: [table].[column] string
Returns:

Table: 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):
6628def alias_(
6629    expression: ExpOrStr,
6630    alias: t.Optional[str | Identifier],
6631    table: bool | t.Sequence[str | Identifier] = False,
6632    quoted: t.Optional[bool] = None,
6633    dialect: DialectType = None,
6634    copy: bool = True,
6635    **opts,
6636):
6637    """Create an Alias expression.
6638
6639    Example:
6640        >>> alias_('foo', 'bar').sql()
6641        'foo AS bar'
6642
6643        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6644        '(SELECT 1, 2) AS bar(a, b)'
6645
6646    Args:
6647        expression: the SQL code strings to parse.
6648            If an Expression instance is passed, this is used as-is.
6649        alias: the alias name to use. If the name has
6650            special characters it is quoted.
6651        table: Whether to create a table alias, can also be a list of columns.
6652        quoted: whether to quote the alias
6653        dialect: the dialect used to parse the input expression.
6654        copy: Whether to copy the expression.
6655        **opts: other options to use to parse the input expressions.
6656
6657    Returns:
6658        Alias: the aliased expression
6659    """
6660    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6661    alias = to_identifier(alias, quoted=quoted)
6662
6663    if table:
6664        table_alias = TableAlias(this=alias)
6665        exp.set("alias", table_alias)
6666
6667        if not isinstance(table, bool):
6668            for column in table:
6669                table_alias.append("columns", to_identifier(column, quoted=quoted))
6670
6671        return exp
6672
6673    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6674    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6675    # for the complete Window expression.
6676    #
6677    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6678
6679    if "alias" in exp.arg_types and not isinstance(exp, Window):
6680        exp.set("alias", alias)
6681        return exp
6682    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:
6685def subquery(
6686    expression: ExpOrStr,
6687    alias: t.Optional[Identifier | str] = None,
6688    dialect: DialectType = None,
6689    **opts,
6690) -> Select:
6691    """
6692    Build a subquery expression that's selected from.
6693
6694    Example:
6695        >>> subquery('select x from tbl', 'bar').select('x').sql()
6696        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6697
6698    Args:
6699        expression: the SQL code strings to parse.
6700            If an Expression instance is passed, this is used as-is.
6701        alias: the alias name to use.
6702        dialect: the dialect used to parse the input expression.
6703        **opts: other options to use to parse the input expressions.
6704
6705    Returns:
6706        A new Select instance with the subquery expression included.
6707    """
6708
6709    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6710    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):
6741def column(
6742    col,
6743    table=None,
6744    db=None,
6745    catalog=None,
6746    *,
6747    fields=None,
6748    quoted=None,
6749    copy=True,
6750):
6751    """
6752    Build a Column.
6753
6754    Args:
6755        col: Column name.
6756        table: Table name.
6757        db: Database name.
6758        catalog: Catalog name.
6759        fields: Additional fields using dots.
6760        quoted: Whether to force quotes on the column's identifiers.
6761        copy: Whether to copy identifiers if passed in.
6762
6763    Returns:
6764        The new Column instance.
6765    """
6766    this = Column(
6767        this=to_identifier(col, quoted=quoted, copy=copy),
6768        table=to_identifier(table, quoted=quoted, copy=copy),
6769        db=to_identifier(db, quoted=quoted, copy=copy),
6770        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6771    )
6772
6773    if fields:
6774        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6775    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:
6778def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6779    """Cast an expression to a data type.
6780
6781    Example:
6782        >>> cast('x + 1', 'int').sql()
6783        'CAST(x + 1 AS INT)'
6784
6785    Args:
6786        expression: The expression to cast.
6787        to: The datatype to cast to.
6788        copy: Whether to copy the supplied expressions.
6789
6790    Returns:
6791        The new Cast instance.
6792    """
6793    expression = maybe_parse(expression, copy=copy, **opts)
6794    data_type = DataType.build(to, copy=copy, **opts)
6795    expression = Cast(this=expression, to=data_type)
6796    expression.type = data_type
6797    return expression

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:
6800def table_(
6801    table: Identifier | str,
6802    db: t.Optional[Identifier | str] = None,
6803    catalog: t.Optional[Identifier | str] = None,
6804    quoted: t.Optional[bool] = None,
6805    alias: t.Optional[Identifier | str] = None,
6806) -> Table:
6807    """Build a Table.
6808
6809    Args:
6810        table: Table name.
6811        db: Database name.
6812        catalog: Catalog name.
6813        quote: Whether to force quotes on the table's identifiers.
6814        alias: Table's alias.
6815
6816    Returns:
6817        The new Table instance.
6818    """
6819    return Table(
6820        this=to_identifier(table, quoted=quoted) if table else None,
6821        db=to_identifier(db, quoted=quoted) if db else None,
6822        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6823        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6824    )

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:
6827def values(
6828    values: t.Iterable[t.Tuple[t.Any, ...]],
6829    alias: t.Optional[str] = None,
6830    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6831) -> Values:
6832    """Build VALUES statement.
6833
6834    Example:
6835        >>> values([(1, '2')]).sql()
6836        "VALUES (1, '2')"
6837
6838    Args:
6839        values: values statements that will be converted to SQL
6840        alias: optional alias
6841        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6842         If either are provided then an alias is also required.
6843
6844    Returns:
6845        Values: the Values expression object
6846    """
6847    if columns and not alias:
6848        raise ValueError("Alias is required when providing columns")
6849
6850    return Values(
6851        expressions=[convert(tup) for tup in values],
6852        alias=(
6853            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6854            if columns
6855            else (TableAlias(this=to_identifier(alias)) if alias else None)
6856        ),
6857    )

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:
6860def var(name: t.Optional[ExpOrStr]) -> Var:
6861    """Build a SQL variable.
6862
6863    Example:
6864        >>> repr(var('x'))
6865        'Var(this=x)'
6866
6867        >>> repr(var(column('x', table='y')))
6868        'Var(this=x)'
6869
6870    Args:
6871        name: The name of the var or an expression who's name will become the var.
6872
6873    Returns:
6874        The new variable node.
6875    """
6876    if not name:
6877        raise ValueError("Cannot convert empty name into var.")
6878
6879    if isinstance(name, Expression):
6880        name = name.name
6881    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) -> AlterTable:
6884def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6885    """Build ALTER TABLE... RENAME... expression
6886
6887    Args:
6888        old_name: The old name of the table
6889        new_name: The new name of the table
6890
6891    Returns:
6892        Alter table expression
6893    """
6894    old_table = to_table(old_name)
6895    new_table = to_table(new_name)
6896    return AlterTable(
6897        this=old_table,
6898        actions=[
6899            RenameTable(this=new_table),
6900        ],
6901    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of 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) -> AlterTable:
6904def rename_column(
6905    table_name: str | Table,
6906    old_column_name: str | Column,
6907    new_column_name: str | Column,
6908    exists: t.Optional[bool] = None,
6909) -> AlterTable:
6910    """Build ALTER TABLE... RENAME COLUMN... expression
6911
6912    Args:
6913        table_name: Name of the table
6914        old_column: The old name of the column
6915        new_column: The new name of the column
6916        exists: Whether to add the `IF EXISTS` clause
6917
6918    Returns:
6919        Alter table expression
6920    """
6921    table = to_table(table_name)
6922    old_column = to_column(old_column_name)
6923    new_column = to_column(new_column_name)
6924    return AlterTable(
6925        this=table,
6926        actions=[
6927            RenameColumn(this=old_column, to=new_column, exists=exists),
6928        ],
6929    )

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

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
6932def convert(value: t.Any, copy: bool = False) -> Expression:
6933    """Convert a python value into an expression object.
6934
6935    Raises an error if a conversion is not possible.
6936
6937    Args:
6938        value: A python object.
6939        copy: Whether to copy `value` (only applies to Expressions and collections).
6940
6941    Returns:
6942        Expression: the equivalent expression object.
6943    """
6944    if isinstance(value, Expression):
6945        return maybe_copy(value, copy)
6946    if isinstance(value, str):
6947        return Literal.string(value)
6948    if isinstance(value, bool):
6949        return Boolean(this=value)
6950    if value is None or (isinstance(value, float) and math.isnan(value)):
6951        return null()
6952    if isinstance(value, numbers.Number):
6953        return Literal.number(value)
6954    if isinstance(value, datetime.datetime):
6955        datetime_literal = Literal.string(
6956            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6957        )
6958        return TimeStrToTime(this=datetime_literal)
6959    if isinstance(value, datetime.date):
6960        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6961        return DateStrToDate(this=date_literal)
6962    if isinstance(value, tuple):
6963        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6964    if isinstance(value, list):
6965        return Array(expressions=[convert(v, copy=copy) for v in value])
6966    if isinstance(value, dict):
6967        return Map(
6968            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6969            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6970        )
6971    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:

Expression: the equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
6974def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6975    """
6976    Replace children of an expression with the result of a lambda fun(child) -> exp.
6977    """
6978    for k, v in tuple(expression.args.items()):
6979        is_list_arg = type(v) is list
6980
6981        child_nodes = v if is_list_arg else [v]
6982        new_child_nodes = []
6983
6984        for cn in child_nodes:
6985            if isinstance(cn, Expression):
6986                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6987                    new_child_nodes.append(child_node)
6988            else:
6989                new_child_nodes.append(cn)
6990
6991        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:
6994def replace_tree(
6995    expression: Expression,
6996    fun: t.Callable,
6997    prune: t.Optional[t.Callable[[Expression], bool]] = None,
6998) -> Expression:
6999    """
7000    Replace an entire tree with the result of function calls on each node.
7001
7002    This will be traversed in reverse dfs, so leaves first.
7003    If new nodes are created as a result of function calls, they will also be traversed.
7004    """
7005    stack = list(expression.dfs(prune=prune))
7006
7007    while stack:
7008        node = stack.pop()
7009        new_node = fun(node)
7010
7011        if new_node is not node:
7012            node.replace(new_node)
7013
7014            if isinstance(new_node, Expression):
7015                stack.append(new_node)
7016
7017    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]:
7020def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7021    """
7022    Return all table names referenced through columns in an expression.
7023
7024    Example:
7025        >>> import sqlglot
7026        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7027        ['a', 'c']
7028
7029    Args:
7030        expression: expression to find table names.
7031        exclude: a table name to exclude
7032
7033    Returns:
7034        A list of unique names.
7035    """
7036    return {
7037        table
7038        for table in (column.table for column in expression.find_all(Column))
7039        if table and table != exclude
7040    }

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:
7043def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7044    """Get the full name of a table as a string.
7045
7046    Args:
7047        table: Table expression node or string.
7048        dialect: The dialect to generate the table name for.
7049        identify: Determines when an identifier should be quoted. Possible values are:
7050            False (default): Never quote, except in cases where it's mandatory by the dialect.
7051            True: Always quote.
7052
7053    Examples:
7054        >>> from sqlglot import exp, parse_one
7055        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7056        'a.b.c'
7057
7058    Returns:
7059        The table name.
7060    """
7061
7062    table = maybe_parse(table, into=Table, dialect=dialect)
7063
7064    if not table:
7065        raise ValueError(f"Cannot parse {table}")
7066
7067    return ".".join(
7068        (
7069            part.sql(dialect=dialect, identify=True, copy=False)
7070            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7071            else part.name
7072        )
7073        for part in table.parts
7074    )

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:
7077def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7078    """Returns a case normalized table name without quotes.
7079
7080    Args:
7081        table: the table to normalize
7082        dialect: the dialect to use for normalization rules
7083        copy: whether to copy the expression.
7084
7085    Examples:
7086        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7087        'A-B.c'
7088    """
7089    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7090
7091    return ".".join(
7092        p.name
7093        for p in normalize_identifiers(
7094            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7095        ).parts
7096    )

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:
7099def replace_tables(
7100    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7101) -> E:
7102    """Replace all tables in expression according to the mapping.
7103
7104    Args:
7105        expression: expression node to be transformed and replaced.
7106        mapping: mapping of table names.
7107        dialect: the dialect of the mapping table
7108        copy: whether to copy the expression.
7109
7110    Examples:
7111        >>> from sqlglot import exp, parse_one
7112        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7113        'SELECT * FROM c /* a.b */'
7114
7115    Returns:
7116        The mapped expression.
7117    """
7118
7119    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7120
7121    def _replace_tables(node: Expression) -> Expression:
7122        if isinstance(node, Table):
7123            original = normalize_table_name(node, dialect=dialect)
7124            new_name = mapping.get(original)
7125
7126            if new_name:
7127                table = to_table(
7128                    new_name,
7129                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7130                    dialect=dialect,
7131                )
7132                table.add_comments([original])
7133                return table
7134        return node
7135
7136    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:
7139def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7140    """Replace placeholders in an expression.
7141
7142    Args:
7143        expression: expression node to be transformed and replaced.
7144        args: positional names that will substitute unnamed placeholders in the given order.
7145        kwargs: keyword arguments that will substitute named placeholders.
7146
7147    Examples:
7148        >>> from sqlglot import exp, parse_one
7149        >>> replace_placeholders(
7150        ...     parse_one("select * from :tbl where ? = ?"),
7151        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7152        ... ).sql()
7153        "SELECT * FROM foo WHERE str_col = 'b'"
7154
7155    Returns:
7156        The mapped expression.
7157    """
7158
7159    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7160        if isinstance(node, Placeholder):
7161            if node.name:
7162                new_name = kwargs.get(node.name)
7163                if new_name is not None:
7164                    return convert(new_name)
7165            else:
7166                try:
7167                    return convert(next(args))
7168                except StopIteration:
7169                    pass
7170        return node
7171
7172    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:
7175def expand(
7176    expression: Expression,
7177    sources: t.Dict[str, Query],
7178    dialect: DialectType = None,
7179    copy: bool = True,
7180) -> Expression:
7181    """Transforms an expression by expanding all referenced sources into subqueries.
7182
7183    Examples:
7184        >>> from sqlglot import parse_one
7185        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7186        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7187
7188        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7189        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7190
7191    Args:
7192        expression: The expression to expand.
7193        sources: A dictionary of name to Queries.
7194        dialect: The dialect of the sources dict.
7195        copy: Whether to copy the expression during transformation. Defaults to True.
7196
7197    Returns:
7198        The transformed expression.
7199    """
7200    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7201
7202    def _expand(node: Expression):
7203        if isinstance(node, Table):
7204            name = normalize_table_name(node, dialect=dialect)
7205            source = sources.get(name)
7206            if source:
7207                subquery = source.subquery(node.alias or name)
7208                subquery.comments = [f"source: {name}"]
7209                return subquery.transform(_expand, copy=False)
7210        return node
7211
7212    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:
7215def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7216    """
7217    Returns a Func expression.
7218
7219    Examples:
7220        >>> func("abs", 5).sql()
7221        'ABS(5)'
7222
7223        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7224        'CAST(5 AS DOUBLE)'
7225
7226    Args:
7227        name: the name of the function to build.
7228        args: the args used to instantiate the function of interest.
7229        copy: whether to copy the argument expressions.
7230        dialect: the source dialect.
7231        kwargs: the kwargs used to instantiate the function of interest.
7232
7233    Note:
7234        The arguments `args` and `kwargs` are mutually exclusive.
7235
7236    Returns:
7237        An instance of the function of interest, or an anonymous function, if `name` doesn't
7238        correspond to an existing `sqlglot.expressions.Func` class.
7239    """
7240    if args and kwargs:
7241        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7242
7243    from sqlglot.dialects.dialect import Dialect
7244
7245    dialect = Dialect.get_or_raise(dialect)
7246
7247    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7248    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7249
7250    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7251    if constructor:
7252        if converted:
7253            if "dialect" in constructor.__code__.co_varnames:
7254                function = constructor(converted, dialect=dialect)
7255            else:
7256                function = constructor(converted)
7257        elif constructor.__name__ == "from_arg_list":
7258            function = constructor.__self__(**kwargs)  # type: ignore
7259        else:
7260            constructor = FUNCTION_BY_NAME.get(name.upper())
7261            if constructor:
7262                function = constructor(**kwargs)
7263            else:
7264                raise ValueError(
7265                    f"Unable to convert '{name}' into a Func. Either manually construct "
7266                    "the Func expression of interest or parse the function call."
7267                )
7268    else:
7269        kwargs = kwargs or {"expressions": converted}
7270        function = Anonymous(this=name, **kwargs)
7271
7272    for error_message in function.error_messages(converted):
7273        raise ValueError(error_message)
7274
7275    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:
7278def case(
7279    expression: t.Optional[ExpOrStr] = None,
7280    **opts,
7281) -> Case:
7282    """
7283    Initialize a CASE statement.
7284
7285    Example:
7286        case().when("a = 1", "foo").else_("bar")
7287
7288    Args:
7289        expression: Optionally, the input expression (not all dialects support this)
7290        **opts: Extra keyword arguments for parsing `expression`
7291    """
7292    if expression is not None:
7293        this = maybe_parse(expression, **opts)
7294    else:
7295        this = None
7296    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 cast_unless( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], *types: Union[str, DataType, DataType.Type], **opts: Any) -> Expression | Cast:
7299def cast_unless(
7300    expression: ExpOrStr,
7301    to: DATA_TYPE,
7302    *types: DATA_TYPE,
7303    **opts: t.Any,
7304) -> Expression | Cast:
7305    """
7306    Cast an expression to a data type unless it is a specified type.
7307
7308    Args:
7309        expression: The expression to cast.
7310        to: The data type to cast to.
7311        **types: The types to exclude from casting.
7312        **opts: Extra keyword arguments for parsing `expression`
7313    """
7314    expr = maybe_parse(expression, **opts)
7315    if expr.is_type(*types):
7316        return expr
7317    return cast(expr, to, **opts)

Cast an expression to a data type unless it is a specified type.

Arguments:
  • expression: The expression to cast.
  • to: The data type to cast to.
  • **types: The types to exclude from casting.
  • **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:
7320def array(
7321    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7322) -> Array:
7323    """
7324    Returns an array.
7325
7326    Examples:
7327        >>> array(1, 'x').sql()
7328        'ARRAY(1, x)'
7329
7330    Args:
7331        expressions: the expressions to add to the array.
7332        copy: whether to copy the argument expressions.
7333        dialect: the source dialect.
7334        kwargs: the kwargs used to instantiate the function of interest.
7335
7336    Returns:
7337        An array expression.
7338    """
7339    return Array(
7340        expressions=[
7341            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7342            for expression in expressions
7343        ]
7344    )

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:
7347def tuple_(
7348    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7349) -> Tuple:
7350    """
7351    Returns an tuple.
7352
7353    Examples:
7354        >>> tuple_(1, 'x').sql()
7355        '(1, x)'
7356
7357    Args:
7358        expressions: the expressions to add to the tuple.
7359        copy: whether to copy the argument expressions.
7360        dialect: the source dialect.
7361        kwargs: the kwargs used to instantiate the function of interest.
7362
7363    Returns:
7364        A tuple expression.
7365    """
7366    return Tuple(
7367        expressions=[
7368            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7369            for expression in expressions
7370        ]
7371    )

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:
7374def true() -> Boolean:
7375    """
7376    Returns a true Boolean expression.
7377    """
7378    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7381def false() -> Boolean:
7382    """
7383    Returns a false Boolean expression.
7384    """
7385    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7388def null() -> Null:
7389    """
7390    Returns a Null expression.
7391    """
7392    return Null()

Returns a Null expression.

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