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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

expressions: List[Any]
141    @property
142    def expressions(self) -> t.List[t.Any]:
143        """
144        Retrieves the argument with key "expressions".
145        """
146        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

is_number: bool
169    @property
170    def is_number(self) -> bool:
171        """
172        Checks whether a Literal expression is a number.
173        """
174        return isinstance(self, Literal) and not self.args["is_string"]

Checks whether a Literal expression is a number.

is_int: bool
176    @property
177    def is_int(self) -> bool:
178        """
179        Checks whether a Literal expression is an integer.
180        """
181        if self.is_number:
182            try:
183                int(self.name)
184                return True
185            except ValueError:
186                pass
187        return False

Checks whether a Literal expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
203    @property
204    def alias_column_names(self) -> t.List[str]:
205        table_alias = self.args.get("alias")
206        if not table_alias:
207            return []
208        return [c.name for c in table_alias.args.get("columns") or []]
name: str
210    @property
211    def name(self) -> str:
212        return self.text("this")
alias_or_name: str
214    @property
215    def alias_or_name(self) -> str:
216        return self.alias or self.name
output_name: str
218    @property
219    def output_name(self) -> str:
220        """
221        Name of the output column if this expression is a selection.
222
223        If the Expression has no output name, an empty string is returned.
224
225        Example:
226            >>> from sqlglot import parse_one
227            >>> parse_one("SELECT a").expressions[0].output_name
228            'a'
229            >>> parse_one("SELECT b AS c").expressions[0].output_name
230            'c'
231            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
232            ''
233        """
234        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]
236    @property
237    def type(self) -> t.Optional[DataType]:
238        return self._type
def is_type(self, *dtypes) -> bool:
246    def is_type(self, *dtypes) -> bool:
247        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
249    def is_leaf(self) -> bool:
250        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
252    @property
253    def meta(self) -> t.Dict[str, t.Any]:
254        if self._meta is None:
255            self._meta = {}
256        return self._meta
def copy(self):
271    def copy(self):
272        """
273        Returns a deep copy of the expression.
274        """
275        new = deepcopy(self)
276        new.parent = self.parent
277        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
279    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
280        if self.comments is None:
281            self.comments = []
282        if comments:
283            for comment in comments:
284                _, *meta = comment.split(SQLGLOT_META)
285                if meta:
286                    for kv in "".join(meta).split(","):
287                        k, *v = kv.split("=")
288                        value = v[0].strip() if v else True
289                        self.meta[k.strip()] = value
290                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
292    def append(self, arg_key: str, value: t.Any) -> None:
293        """
294        Appends value to arg_key if it's a list or sets it as a new list.
295
296        Args:
297            arg_key (str): name of the list expression arg
298            value (Any): value to append to the list
299        """
300        if not isinstance(self.args.get(arg_key), list):
301            self.args[arg_key] = []
302        self.args[arg_key].append(value)
303        self._set_parent(arg_key, 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:
305    def set(self, arg_key: str, value: t.Any) -> None:
306        """
307        Sets arg_key to value.
308
309        Args:
310            arg_key: name of the expression arg.
311            value: value to set the arg to.
312        """
313        if value is None:
314            self.args.pop(arg_key, None)
315            return
316
317        self.args[arg_key] = value
318        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
330    @property
331    def depth(self) -> int:
332        """
333        Returns the depth of this tree.
334        """
335        if self.parent:
336            return self.parent.depth + 1
337        return 0

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
339    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
340        """Yields the key and expression for all arguments, exploding list args."""
341        for k, vs in self.args.items():
342            if type(vs) is list:
343                for v in vs:
344                    if hasattr(v, "parent"):
345                        yield k, v
346            else:
347                if hasattr(vs, "parent"):
348                    yield k, vs

Yields the key and expression for all arguments, exploding list args.

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
350    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
351        """
352        Returns the first node in this tree which matches at least one of
353        the specified types.
354
355        Args:
356            expression_types: the expression type(s) to match.
357            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
358
359        Returns:
360            The node which matches the criteria or None if no such node was found.
361        """
362        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]:
364    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
365        """
366        Returns a generator object which visits all nodes in this tree and only
367        yields those that match at least one of the specified expression types.
368
369        Args:
370            expression_types: the expression type(s) to match.
371            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
372
373        Returns:
374            The generator object.
375        """
376        for expression, *_ in self.walk(bfs=bfs):
377            if isinstance(expression, expression_types):
378                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]:
380    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
381        """
382        Returns a nearest parent matching expression_types.
383
384        Args:
385            expression_types: the expression type(s) to match.
386
387        Returns:
388            The parent node.
389        """
390        ancestor = self.parent
391        while ancestor and not isinstance(ancestor, expression_types):
392            ancestor = ancestor.parent
393        return t.cast(E, ancestor)

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]
395    @property
396    def parent_select(self) -> t.Optional[Select]:
397        """
398        Returns the parent select statement.
399        """
400        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
402    @property
403    def same_parent(self) -> bool:
404        """Returns if the parent is the same class as itself."""
405        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
407    def root(self) -> Expression:
408        """
409        Returns the root expression of this tree.
410        """
411        expression = self
412        while expression.parent:
413            expression = expression.parent
414        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
416    def walk(self, bfs=True, prune=None):
417        """
418        Returns a generator object which visits all nodes in this tree.
419
420        Args:
421            bfs (bool): if set to True the BFS traversal order will be applied,
422                otherwise the DFS traversal will be used instead.
423            prune ((node, parent, arg_key) -> bool): callable that returns True if
424                the generator should stop traversing this branch of the tree.
425
426        Returns:
427            the generator object.
428        """
429        if bfs:
430            yield from self.bfs(prune=prune)
431        else:
432            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, parent=None, key=None, prune=None):
434    def dfs(self, parent=None, key=None, prune=None):
435        """
436        Returns a generator object which visits all nodes in this tree in
437        the DFS (Depth-first) order.
438
439        Returns:
440            The generator object.
441        """
442        parent = parent or self.parent
443        yield self, parent, key
444        if prune and prune(self, parent, key):
445            return
446
447        for k, v in self.iter_expressions():
448            yield from v.dfs(self, k, prune)

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=None):
450    def bfs(self, prune=None):
451        """
452        Returns a generator object which visits all nodes in this tree in
453        the BFS (Breadth-first) order.
454
455        Returns:
456            The generator object.
457        """
458        queue = deque([(self, self.parent, None)])
459
460        while queue:
461            item, parent, key = queue.popleft()
462
463            yield item, parent, key
464            if prune and prune(item, parent, key):
465                continue
466
467            for k, v in item.iter_expressions():
468                queue.append((v, item, k))

Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.

Returns:

The generator object.

def unnest(self):
470    def unnest(self):
471        """
472        Returns the first non parenthesis child or self.
473        """
474        expression = self
475        while type(expression) is Paren:
476            expression = expression.this
477        return expression

Returns the first non parenthesis child or self.

def unalias(self):
479    def unalias(self):
480        """
481        Returns the inner expression if this is an Alias.
482        """
483        if isinstance(self, Alias):
484            return self.this
485        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
487    def unnest_operands(self):
488        """
489        Returns unnested operands as a tuple.
490        """
491        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
493    def flatten(self, unnest=True):
494        """
495        Returns a generator which yields child nodes whose parents are the same class.
496
497        A AND B AND C -> [A, B, C]
498        """
499        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
500            if not type(node) is self.__class__:
501                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:
509    def to_s(self) -> str:
510        """
511        Same as __repr__, but includes additional information which can be useful
512        for debugging, like empty or missing args and the AST nodes' object IDs.
513        """
514        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:
516    def sql(self, dialect: DialectType = None, **opts) -> str:
517        """
518        Returns SQL string representation of this tree.
519
520        Args:
521            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
522            opts: other `sqlglot.generator.Generator` options.
523
524        Returns:
525            The SQL string.
526        """
527        from sqlglot.dialects import Dialect
528
529        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, *args, copy=True, **kwargs):
531    def transform(self, fun, *args, copy=True, **kwargs):
532        """
533        Recursively visits all tree nodes (excluding already transformed ones)
534        and applies the given transformation function to each node.
535
536        Args:
537            fun (function): a function which takes a node as an argument and returns a
538                new transformed node or the same node without modifications. If the function
539                returns None, then the corresponding node will be removed from the syntax tree.
540            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
541                modified in place.
542
543        Returns:
544            The transformed tree.
545        """
546        node = self.copy() if copy else self
547        new_node = fun(node, *args, **kwargs)
548
549        if new_node is None or not isinstance(new_node, Expression):
550            return new_node
551        if new_node is not node:
552            new_node.parent = node.parent
553            return new_node
554
555        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
556        return new_node

Recursively 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):
566    def replace(self, expression):
567        """
568        Swap out this expression with a new expression.
569
570        For example::
571
572            >>> tree = Select().select("x").from_("tbl")
573            >>> tree.find(Column).replace(column("y"))
574            Column(
575              this=Identifier(this=y, quoted=False))
576            >>> tree.sql()
577            'SELECT y FROM tbl'
578
579        Args:
580            expression: new node
581
582        Returns:
583            The new expression or expressions.
584        """
585        if not self.parent:
586            return expression
587
588        parent = self.parent
589        self.parent = None
590
591        replace_children(parent, lambda child: expression if child is self else child)
592        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:
594    def pop(self: E) -> E:
595        """
596        Remove this expression from its AST.
597
598        Returns:
599            The popped expression.
600        """
601        self.replace(None)
602        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
604    def assert_is(self, type_: t.Type[E]) -> E:
605        """
606        Assert that this `Expression` is an instance of `type_`.
607
608        If it is NOT an instance of `type_`, this raises an assertion error.
609        Otherwise, this returns this expression.
610
611        Examples:
612            This is useful for type security in chained expressions:
613
614            >>> import sqlglot
615            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
616            'SELECT x, z FROM y'
617        """
618        assert isinstance(self, type_)
619        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]:
621    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
622        """
623        Checks if this expression is valid (e.g. all mandatory args are set).
624
625        Args:
626            args: a sequence of values that were used to instantiate a Func expression. This is used
627                to check that the provided arguments don't exceed the function argument limit.
628
629        Returns:
630            A list of error messages for all possible errors that were found.
631        """
632        errors: t.List[str] = []
633
634        for k in self.args:
635            if k not in self.arg_types:
636                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
637        for k, mandatory in self.arg_types.items():
638            v = self.args.get(k)
639            if mandatory and (v is None or (isinstance(v, list) and not v)):
640                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
641
642        if (
643            args
644            and isinstance(self, Func)
645            and len(args) > len(self.arg_types)
646            and not self.is_var_len_args
647        ):
648            errors.append(
649                f"The number of provided arguments ({len(args)}) is greater than "
650                f"the maximum number of supported arguments ({len(self.arg_types)})"
651            )
652
653        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):
655    def dump(self):
656        """
657        Dump this Expression to a JSON-serializable dict.
658        """
659        from sqlglot.serde import dump
660
661        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
663    @classmethod
664    def load(cls, obj):
665        """
666        Load a dict (as returned by `Expression.dump`) into an Expression instance.
667        """
668        from sqlglot.serde import load
669
670        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:
672    def and_(
673        self,
674        *expressions: t.Optional[ExpOrStr],
675        dialect: DialectType = None,
676        copy: bool = True,
677        **opts,
678    ) -> Condition:
679        """
680        AND this condition with one or multiple expressions.
681
682        Example:
683            >>> condition("x=1").and_("y=1").sql()
684            'x = 1 AND y = 1'
685
686        Args:
687            *expressions: the SQL code strings to parse.
688                If an `Expression` instance is passed, it will be used as-is.
689            dialect: the dialect used to parse the input expression.
690            copy: whether or not to copy the involved expressions (only applies to Expressions).
691            opts: other options to use to parse the input expressions.
692
693        Returns:
694            The new And condition.
695        """
696        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 or not 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:
698    def or_(
699        self,
700        *expressions: t.Optional[ExpOrStr],
701        dialect: DialectType = None,
702        copy: bool = True,
703        **opts,
704    ) -> Condition:
705        """
706        OR this condition with one or multiple expressions.
707
708        Example:
709            >>> condition("x=1").or_("y=1").sql()
710            'x = 1 OR y = 1'
711
712        Args:
713            *expressions: the SQL code strings to parse.
714                If an `Expression` instance is passed, it will be used as-is.
715            dialect: the dialect used to parse the input expression.
716            copy: whether or not to copy the involved expressions (only applies to Expressions).
717            opts: other options to use to parse the input expressions.
718
719        Returns:
720            The new Or condition.
721        """
722        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 or not 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):
724    def not_(self, copy: bool = True):
725        """
726        Wrap this condition with NOT.
727
728        Example:
729            >>> condition("x=1").not_().sql()
730            'NOT x = 1'
731
732        Args:
733            copy: whether or not to copy this object.
734
735        Returns:
736            The new Not instance.
737        """
738        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether or not 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:
740    def as_(
741        self,
742        alias: str | Identifier,
743        quoted: t.Optional[bool] = None,
744        dialect: DialectType = None,
745        copy: bool = True,
746        **opts,
747    ) -> Alias:
748        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:
773    def isin(
774        self,
775        *expressions: t.Any,
776        query: t.Optional[ExpOrStr] = None,
777        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
778        copy: bool = True,
779        **opts,
780    ) -> In:
781        return In(
782            this=maybe_copy(self, copy),
783            expressions=[convert(e, copy=copy) for e in expressions],
784            query=maybe_parse(query, copy=copy, **opts) if query else None,
785            unnest=Unnest(
786                expressions=[
787                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
788                ]
789            )
790            if unnest
791            else None,
792        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
794    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
795        return Between(
796            this=maybe_copy(self, copy),
797            low=convert(low, copy=copy, **opts),
798            high=convert(high, copy=copy, **opts),
799        )
def is_( self, other: Union[str, Expression]) -> Is:
801    def is_(self, other: ExpOrStr) -> Is:
802        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
804    def like(self, other: ExpOrStr) -> Like:
805        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
807    def ilike(self, other: ExpOrStr) -> ILike:
808        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
810    def eq(self, other: t.Any) -> EQ:
811        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
813    def neq(self, other: t.Any) -> NEQ:
814        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
816    def rlike(self, other: ExpOrStr) -> RegexpLike:
817        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
819    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
820        div = self._binop(Div, other)
821        div.args["typed"] = typed
822        div.args["safe"] = safe
823        return div
def desc(self, nulls_first: bool = False) -> Ordered:
825    def desc(self, nulls_first: bool = False) -> Ordered:
826        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):
909class Condition(Expression):
910    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
917class DerivedTable(Expression):
918    @property
919    def selects(self) -> t.List[Expression]:
920        return self.this.selects if isinstance(self.this, Subqueryable) else []
921
922    @property
923    def named_selects(self) -> t.List[str]:
924        return [select.output_name for select in self.selects]
selects: List[Expression]
918    @property
919    def selects(self) -> t.List[Expression]:
920        return self.this.selects if isinstance(self.this, Subqueryable) else []
named_selects: List[str]
922    @property
923    def named_selects(self) -> t.List[str]:
924        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Unionable(Expression):
927class Unionable(Expression):
928    def union(
929        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
930    ) -> Unionable:
931        """
932        Builds a UNION expression.
933
934        Example:
935            >>> import sqlglot
936            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
937            'SELECT * FROM foo UNION SELECT * FROM bla'
938
939        Args:
940            expression: the SQL code string.
941                If an `Expression` instance is passed, it will be used as-is.
942            distinct: set the DISTINCT flag if and only if this is true.
943            dialect: the dialect used to parse the input expression.
944            opts: other options to use to parse the input expressions.
945
946        Returns:
947            The new Union expression.
948        """
949        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
950
951    def intersect(
952        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
953    ) -> Unionable:
954        """
955        Builds an INTERSECT expression.
956
957        Example:
958            >>> import sqlglot
959            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
960            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
961
962        Args:
963            expression: the SQL code string.
964                If an `Expression` instance is passed, it will be used as-is.
965            distinct: set the DISTINCT flag if and only if this is true.
966            dialect: the dialect used to parse the input expression.
967            opts: other options to use to parse the input expressions.
968
969        Returns:
970            The new Intersect expression.
971        """
972        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
973
974    def except_(
975        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
976    ) -> Unionable:
977        """
978        Builds an EXCEPT expression.
979
980        Example:
981            >>> import sqlglot
982            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
983            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
984
985        Args:
986            expression: the SQL code string.
987                If an `Expression` instance is passed, it will be used as-is.
988            distinct: set the DISTINCT flag if and only if this is true.
989            dialect: the dialect used to parse the input expression.
990            opts: other options to use to parse the input expressions.
991
992        Returns:
993            The new Except expression.
994        """
995        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
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) -> Unionable:
928    def union(
929        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
930    ) -> Unionable:
931        """
932        Builds a UNION expression.
933
934        Example:
935            >>> import sqlglot
936            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
937            'SELECT * FROM foo UNION SELECT * FROM bla'
938
939        Args:
940            expression: the SQL code string.
941                If an `Expression` instance is passed, it will be used as-is.
942            distinct: set the DISTINCT flag if and only if this is true.
943            dialect: the dialect used to parse the input expression.
944            opts: other options to use to parse the input expressions.
945
946        Returns:
947            The new Union expression.
948        """
949        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) -> Unionable:
951    def intersect(
952        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
953    ) -> Unionable:
954        """
955        Builds an INTERSECT expression.
956
957        Example:
958            >>> import sqlglot
959            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
960            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
961
962        Args:
963            expression: the SQL code string.
964                If an `Expression` instance is passed, it will be used as-is.
965            distinct: set the DISTINCT flag if and only if this is true.
966            dialect: the dialect used to parse the input expression.
967            opts: other options to use to parse the input expressions.
968
969        Returns:
970            The new Intersect expression.
971        """
972        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) -> Unionable:
974    def except_(
975        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
976    ) -> Unionable:
977        """
978        Builds an EXCEPT expression.
979
980        Example:
981            >>> import sqlglot
982            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
983            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
984
985        Args:
986            expression: the SQL code string.
987                If an `Expression` instance is passed, it will be used as-is.
988            distinct: set the DISTINCT flag if and only if this is true.
989            dialect: the dialect used to parse the input expression.
990            opts: other options to use to parse the input expressions.
991
992        Returns:
993            The new Except expression.
994        """
995        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 = 'unionable'
class UDTF(DerivedTable, Unionable):
 998class UDTF(DerivedTable, Unionable):
 999    @property
1000    def selects(self) -> t.List[Expression]:
1001        alias = self.args.get("alias")
1002        return alias.columns if alias else []
selects: List[Expression]
 999    @property
1000    def selects(self) -> t.List[Expression]:
1001        alias = self.args.get("alias")
1002        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1005class Cache(Expression):
1006    arg_types = {
1007        "this": True,
1008        "lazy": False,
1009        "options": False,
1010        "expression": False,
1011    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1014class Uncache(Expression):
1015    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1018class Refresh(Expression):
1019    pass
key = 'refresh'
class DDL(Expression):
1022class DDL(Expression):
1023    @property
1024    def ctes(self):
1025        with_ = self.args.get("with")
1026        if not with_:
1027            return []
1028        return with_.expressions
1029
1030    @property
1031    def named_selects(self) -> t.List[str]:
1032        if isinstance(self.expression, Subqueryable):
1033            return self.expression.named_selects
1034        return []
1035
1036    @property
1037    def selects(self) -> t.List[Expression]:
1038        if isinstance(self.expression, Subqueryable):
1039            return self.expression.selects
1040        return []
ctes
1023    @property
1024    def ctes(self):
1025        with_ = self.args.get("with")
1026        if not with_:
1027            return []
1028        return with_.expressions
named_selects: List[str]
1030    @property
1031    def named_selects(self) -> t.List[str]:
1032        if isinstance(self.expression, Subqueryable):
1033            return self.expression.named_selects
1034        return []
selects: List[Expression]
1036    @property
1037    def selects(self) -> t.List[Expression]:
1038        if isinstance(self.expression, Subqueryable):
1039            return self.expression.selects
1040        return []
key = 'ddl'
class DML(Expression):
1043class DML(Expression):
1044    def returning(
1045        self,
1046        expression: ExpOrStr,
1047        dialect: DialectType = None,
1048        copy: bool = True,
1049        **opts,
1050    ) -> DML:
1051        """
1052        Set the RETURNING expression. Not supported by all dialects.
1053
1054        Example:
1055            >>> delete("tbl").returning("*", dialect="postgres").sql()
1056            'DELETE FROM tbl RETURNING *'
1057
1058        Args:
1059            expression: the SQL code strings to parse.
1060                If an `Expression` instance is passed, it will be used as-is.
1061            dialect: the dialect used to parse the input expressions.
1062            copy: if `False`, modify this expression instance in-place.
1063            opts: other options to use to parse the input expressions.
1064
1065        Returns:
1066            Delete: the modified expression.
1067        """
1068        return _apply_builder(
1069            expression=expression,
1070            instance=self,
1071            arg="returning",
1072            prefix="RETURNING",
1073            dialect=dialect,
1074            copy=copy,
1075            into=Returning,
1076            **opts,
1077        )
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:
1044    def returning(
1045        self,
1046        expression: ExpOrStr,
1047        dialect: DialectType = None,
1048        copy: bool = True,
1049        **opts,
1050    ) -> DML:
1051        """
1052        Set the RETURNING expression. Not supported by all dialects.
1053
1054        Example:
1055            >>> delete("tbl").returning("*", dialect="postgres").sql()
1056            'DELETE FROM tbl RETURNING *'
1057
1058        Args:
1059            expression: the SQL code strings to parse.
1060                If an `Expression` instance is passed, it will be used as-is.
1061            dialect: the dialect used to parse the input expressions.
1062            copy: if `False`, modify this expression instance in-place.
1063            opts: other options to use to parse the input expressions.
1064
1065        Returns:
1066            Delete: the modified expression.
1067        """
1068        return _apply_builder(
1069            expression=expression,
1070            instance=self,
1071            arg="returning",
1072            prefix="RETURNING",
1073            dialect=dialect,
1074            copy=copy,
1075            into=Returning,
1076            **opts,
1077        )

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):
1080class Create(DDL):
1081    arg_types = {
1082        "with": False,
1083        "this": True,
1084        "kind": True,
1085        "expression": False,
1086        "exists": False,
1087        "properties": False,
1088        "replace": False,
1089        "unique": False,
1090        "indexes": False,
1091        "no_schema_binding": False,
1092        "begin": False,
1093        "end": False,
1094        "clone": False,
1095    }
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}
key = 'create'
class Clone(Expression):
1101class Clone(Expression):
1102    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1105class Describe(Expression):
1106    arg_types = {"this": True, "kind": False, "expressions": False}
arg_types = {'this': True, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1109class Kill(Expression):
1110    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1113class Pragma(Expression):
1114    pass
key = 'pragma'
class Set(Expression):
1117class Set(Expression):
1118    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class SetItem(Expression):
1121class SetItem(Expression):
1122    arg_types = {
1123        "this": False,
1124        "expressions": False,
1125        "kind": False,
1126        "collate": False,  # MySQL SET NAMES statement
1127        "global": False,
1128    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1131class Show(Expression):
1132    arg_types = {
1133        "this": True,
1134        "target": False,
1135        "offset": False,
1136        "limit": False,
1137        "like": False,
1138        "where": False,
1139        "db": False,
1140        "scope": False,
1141        "scope_kind": False,
1142        "full": False,
1143        "mutex": False,
1144        "query": False,
1145        "channel": False,
1146        "global": False,
1147        "log": False,
1148        "position": False,
1149        "types": False,
1150    }
arg_types = {'this': True, 'target': False, 'offset': False, 'limit': 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):
1153class UserDefinedFunction(Expression):
1154    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1157class CharacterSet(Expression):
1158    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1161class With(Expression):
1162    arg_types = {"expressions": True, "recursive": False}
1163
1164    @property
1165    def recursive(self) -> bool:
1166        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1164    @property
1165    def recursive(self) -> bool:
1166        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1169class WithinGroup(Expression):
1170    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1175class CTE(DerivedTable):
1176    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1179class TableAlias(Expression):
1180    arg_types = {"this": False, "columns": False}
1181
1182    @property
1183    def columns(self):
1184        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1182    @property
1183    def columns(self):
1184        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1187class BitString(Condition):
1188    pass
key = 'bitstring'
class HexString(Condition):
1191class HexString(Condition):
1192    pass
key = 'hexstring'
class ByteString(Condition):
1195class ByteString(Condition):
1196    pass
key = 'bytestring'
class RawString(Condition):
1199class RawString(Condition):
1200    pass
key = 'rawstring'
class UnicodeString(Condition):
1203class UnicodeString(Condition):
1204    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1207class Column(Condition):
1208    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1209
1210    @property
1211    def table(self) -> str:
1212        return self.text("table")
1213
1214    @property
1215    def db(self) -> str:
1216        return self.text("db")
1217
1218    @property
1219    def catalog(self) -> str:
1220        return self.text("catalog")
1221
1222    @property
1223    def output_name(self) -> str:
1224        return self.name
1225
1226    @property
1227    def parts(self) -> t.List[Identifier]:
1228        """Return the parts of a column in order catalog, db, table, name."""
1229        return [
1230            t.cast(Identifier, self.args[part])
1231            for part in ("catalog", "db", "table", "this")
1232            if self.args.get(part)
1233        ]
1234
1235    def to_dot(self) -> Dot | Identifier:
1236        """Converts the column into a dot expression."""
1237        parts = self.parts
1238        parent = self.parent
1239
1240        while parent:
1241            if isinstance(parent, Dot):
1242                parts.append(parent.expression)
1243            parent = parent.parent
1244
1245        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
1210    @property
1211    def table(self) -> str:
1212        return self.text("table")
db: str
1214    @property
1215    def db(self) -> str:
1216        return self.text("db")
catalog: str
1218    @property
1219    def catalog(self) -> str:
1220        return self.text("catalog")
output_name: str
1222    @property
1223    def output_name(self) -> str:
1224        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]
1226    @property
1227    def parts(self) -> t.List[Identifier]:
1228        """Return the parts of a column in order catalog, db, table, name."""
1229        return [
1230            t.cast(Identifier, self.args[part])
1231            for part in ("catalog", "db", "table", "this")
1232            if self.args.get(part)
1233        ]

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

def to_dot(self) -> Dot | Identifier:
1235    def to_dot(self) -> Dot | Identifier:
1236        """Converts the column into a dot expression."""
1237        parts = self.parts
1238        parent = self.parent
1239
1240        while parent:
1241            if isinstance(parent, Dot):
1242                parts.append(parent.expression)
1243            parent = parent.parent
1244
1245        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1248class ColumnPosition(Expression):
1249    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1252class ColumnDef(Expression):
1253    arg_types = {
1254        "this": True,
1255        "kind": False,
1256        "constraints": False,
1257        "exists": False,
1258        "position": False,
1259    }
1260
1261    @property
1262    def constraints(self) -> t.List[ColumnConstraint]:
1263        return self.args.get("constraints") or []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1261    @property
1262    def constraints(self) -> t.List[ColumnConstraint]:
1263        return self.args.get("constraints") or []
key = 'columndef'
class AlterColumn(Expression):
1266class AlterColumn(Expression):
1267    arg_types = {
1268        "this": True,
1269        "dtype": False,
1270        "collate": False,
1271        "using": False,
1272        "default": False,
1273        "drop": False,
1274    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1277class RenameTable(Expression):
1278    pass
key = 'renametable'
class SwapTable(Expression):
1281class SwapTable(Expression):
1282    pass
key = 'swaptable'
class Comment(Expression):
1285class Comment(Expression):
1286    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):
1289class Comprehension(Expression):
1290    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):
1294class MergeTreeTTLAction(Expression):
1295    arg_types = {
1296        "this": True,
1297        "delete": False,
1298        "recompress": False,
1299        "to_disk": False,
1300        "to_volume": False,
1301    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1305class MergeTreeTTL(Expression):
1306    arg_types = {
1307        "expressions": True,
1308        "where": False,
1309        "group": False,
1310        "aggregates": False,
1311    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1315class IndexConstraintOption(Expression):
1316    arg_types = {
1317        "key_block_size": False,
1318        "using": False,
1319        "parser": False,
1320        "comment": False,
1321        "visible": False,
1322        "engine_attr": False,
1323        "secondary_engine_attr": False,
1324    }
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):
1327class ColumnConstraint(Expression):
1328    arg_types = {"this": False, "kind": True}
1329
1330    @property
1331    def kind(self) -> ColumnConstraintKind:
1332        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1330    @property
1331    def kind(self) -> ColumnConstraintKind:
1332        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1335class ColumnConstraintKind(Expression):
1336    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1339class AutoIncrementColumnConstraint(ColumnConstraintKind):
1340    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1343class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1344    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1347class CaseSpecificColumnConstraint(ColumnConstraintKind):
1348    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1351class CharacterSetColumnConstraint(ColumnConstraintKind):
1352    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1355class CheckColumnConstraint(ColumnConstraintKind):
1356    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1359class ClusteredColumnConstraint(ColumnConstraintKind):
1360    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1363class CollateColumnConstraint(ColumnConstraintKind):
1364    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1367class CommentColumnConstraint(ColumnConstraintKind):
1368    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1371class CompressColumnConstraint(ColumnConstraintKind):
1372    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1375class DateFormatColumnConstraint(ColumnConstraintKind):
1376    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1379class DefaultColumnConstraint(ColumnConstraintKind):
1380    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1383class EncodeColumnConstraint(ColumnConstraintKind):
1384    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1387class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1388    # this: True -> ALWAYS, this: False -> BY DEFAULT
1389    arg_types = {
1390        "this": False,
1391        "expression": False,
1392        "on_null": False,
1393        "start": False,
1394        "increment": False,
1395        "minvalue": False,
1396        "maxvalue": False,
1397        "cycle": False,
1398    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1401class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1402    arg_types = {"start": True, "hidden": False}
arg_types = {'start': True, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1406class IndexColumnConstraint(ColumnConstraintKind):
1407    arg_types = {
1408        "this": False,
1409        "schema": True,
1410        "kind": False,
1411        "index_type": False,
1412        "options": False,
1413    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1416class InlineLengthColumnConstraint(ColumnConstraintKind):
1417    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1420class NonClusteredColumnConstraint(ColumnConstraintKind):
1421    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1424class NotForReplicationColumnConstraint(ColumnConstraintKind):
1425    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1428class NotNullColumnConstraint(ColumnConstraintKind):
1429    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1433class OnUpdateColumnConstraint(ColumnConstraintKind):
1434    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1438class TransformColumnConstraint(ColumnConstraintKind):
1439    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1442class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1443    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1446class TitleColumnConstraint(ColumnConstraintKind):
1447    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1450class UniqueColumnConstraint(ColumnConstraintKind):
1451    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1454class UppercaseColumnConstraint(ColumnConstraintKind):
1455    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1458class PathColumnConstraint(ColumnConstraintKind):
1459    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1464class ComputedColumnConstraint(ColumnConstraintKind):
1465    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1468class Constraint(Expression):
1469    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1472class Delete(DML):
1473    arg_types = {
1474        "with": False,
1475        "this": False,
1476        "using": False,
1477        "where": False,
1478        "returning": False,
1479        "limit": False,
1480        "tables": False,  # Multiple-Table Syntax (MySQL)
1481    }
1482
1483    def delete(
1484        self,
1485        table: ExpOrStr,
1486        dialect: DialectType = None,
1487        copy: bool = True,
1488        **opts,
1489    ) -> Delete:
1490        """
1491        Create a DELETE expression or replace the table on an existing DELETE expression.
1492
1493        Example:
1494            >>> delete("tbl").sql()
1495            'DELETE FROM tbl'
1496
1497        Args:
1498            table: the table from which to delete.
1499            dialect: the dialect used to parse the input expression.
1500            copy: if `False`, modify this expression instance in-place.
1501            opts: other options to use to parse the input expressions.
1502
1503        Returns:
1504            Delete: the modified expression.
1505        """
1506        return _apply_builder(
1507            expression=table,
1508            instance=self,
1509            arg="this",
1510            dialect=dialect,
1511            into=Table,
1512            copy=copy,
1513            **opts,
1514        )
1515
1516    def where(
1517        self,
1518        *expressions: t.Optional[ExpOrStr],
1519        append: bool = True,
1520        dialect: DialectType = None,
1521        copy: bool = True,
1522        **opts,
1523    ) -> Delete:
1524        """
1525        Append to or set the WHERE expressions.
1526
1527        Example:
1528            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1529            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1530
1531        Args:
1532            *expressions: the SQL code strings to parse.
1533                If an `Expression` instance is passed, it will be used as-is.
1534                Multiple expressions are combined with an AND operator.
1535            append: if `True`, AND the new expressions to any existing expression.
1536                Otherwise, this resets the expression.
1537            dialect: the dialect used to parse the input expressions.
1538            copy: if `False`, modify this expression instance in-place.
1539            opts: other options to use to parse the input expressions.
1540
1541        Returns:
1542            Delete: the modified expression.
1543        """
1544        return _apply_conjunction_builder(
1545            *expressions,
1546            instance=self,
1547            arg="where",
1548            append=append,
1549            into=Where,
1550            dialect=dialect,
1551            copy=copy,
1552            **opts,
1553        )
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:
1483    def delete(
1484        self,
1485        table: ExpOrStr,
1486        dialect: DialectType = None,
1487        copy: bool = True,
1488        **opts,
1489    ) -> Delete:
1490        """
1491        Create a DELETE expression or replace the table on an existing DELETE expression.
1492
1493        Example:
1494            >>> delete("tbl").sql()
1495            'DELETE FROM tbl'
1496
1497        Args:
1498            table: the table from which to delete.
1499            dialect: the dialect used to parse the input expression.
1500            copy: if `False`, modify this expression instance in-place.
1501            opts: other options to use to parse the input expressions.
1502
1503        Returns:
1504            Delete: the modified expression.
1505        """
1506        return _apply_builder(
1507            expression=table,
1508            instance=self,
1509            arg="this",
1510            dialect=dialect,
1511            into=Table,
1512            copy=copy,
1513            **opts,
1514        )

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:
1516    def where(
1517        self,
1518        *expressions: t.Optional[ExpOrStr],
1519        append: bool = True,
1520        dialect: DialectType = None,
1521        copy: bool = True,
1522        **opts,
1523    ) -> Delete:
1524        """
1525        Append to or set the WHERE expressions.
1526
1527        Example:
1528            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1529            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1530
1531        Args:
1532            *expressions: the SQL code strings to parse.
1533                If an `Expression` instance is passed, it will be used as-is.
1534                Multiple expressions are combined with an AND operator.
1535            append: if `True`, AND the new expressions to any existing expression.
1536                Otherwise, this resets the expression.
1537            dialect: the dialect used to parse the input expressions.
1538            copy: if `False`, modify this expression instance in-place.
1539            opts: other options to use to parse the input expressions.
1540
1541        Returns:
1542            Delete: the modified expression.
1543        """
1544        return _apply_conjunction_builder(
1545            *expressions,
1546            instance=self,
1547            arg="where",
1548            append=append,
1549            into=Where,
1550            dialect=dialect,
1551            copy=copy,
1552            **opts,
1553        )

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):
1556class Drop(Expression):
1557    arg_types = {
1558        "this": False,
1559        "kind": False,
1560        "exists": False,
1561        "temporary": False,
1562        "materialized": False,
1563        "cascade": False,
1564        "constraints": False,
1565        "purge": False,
1566    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1569class Filter(Expression):
1570    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1573class Check(Expression):
1574    pass
key = 'check'
class Connect(Expression):
1578class Connect(Expression):
1579    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1582class Prior(Expression):
1583    pass
key = 'prior'
class Directory(Expression):
1586class Directory(Expression):
1587    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1588    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1591class ForeignKey(Expression):
1592    arg_types = {
1593        "expressions": True,
1594        "reference": False,
1595        "delete": False,
1596        "update": False,
1597    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1600class ColumnPrefix(Expression):
1601    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1604class PrimaryKey(Expression):
1605    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1610class Into(Expression):
1611    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1614class From(Expression):
1615    @property
1616    def name(self) -> str:
1617        return self.this.name
1618
1619    @property
1620    def alias_or_name(self) -> str:
1621        return self.this.alias_or_name
name: str
1615    @property
1616    def name(self) -> str:
1617        return self.this.name
alias_or_name: str
1619    @property
1620    def alias_or_name(self) -> str:
1621        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1624class Having(Expression):
1625    pass
key = 'having'
class Hint(Expression):
1628class Hint(Expression):
1629    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1632class JoinHint(Expression):
1633    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1636class Identifier(Expression):
1637    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1638
1639    @property
1640    def quoted(self) -> bool:
1641        return bool(self.args.get("quoted"))
1642
1643    @property
1644    def hashable_args(self) -> t.Any:
1645        return (self.this, self.quoted)
1646
1647    @property
1648    def output_name(self) -> str:
1649        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1639    @property
1640    def quoted(self) -> bool:
1641        return bool(self.args.get("quoted"))
hashable_args: Any
1643    @property
1644    def hashable_args(self) -> t.Any:
1645        return (self.this, self.quoted)
output_name: str
1647    @property
1648    def output_name(self) -> str:
1649        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):
1653class Opclass(Expression):
1654    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1657class Index(Expression):
1658    arg_types = {
1659        "this": False,
1660        "table": False,
1661        "using": False,
1662        "where": False,
1663        "columns": False,
1664        "unique": False,
1665        "primary": False,
1666        "amp": False,  # teradata
1667        "partition_by": False,  # teradata
1668        "where": False,  # postgres partial indexes
1669    }
arg_types = {'this': False, 'table': False, 'using': False, 'where': False, 'columns': False, 'unique': False, 'primary': False, 'amp': False, 'partition_by': False}
key = 'index'
class Insert(DDL, DML):
1672class Insert(DDL, DML):
1673    arg_types = {
1674        "with": False,
1675        "this": True,
1676        "expression": False,
1677        "conflict": False,
1678        "returning": False,
1679        "overwrite": False,
1680        "exists": False,
1681        "partition": False,
1682        "alternative": False,
1683        "where": False,
1684        "ignore": False,
1685        "by_name": False,
1686    }
1687
1688    def with_(
1689        self,
1690        alias: ExpOrStr,
1691        as_: ExpOrStr,
1692        recursive: t.Optional[bool] = None,
1693        append: bool = True,
1694        dialect: DialectType = None,
1695        copy: bool = True,
1696        **opts,
1697    ) -> Insert:
1698        """
1699        Append to or set the common table expressions.
1700
1701        Example:
1702            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1703            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1704
1705        Args:
1706            alias: the SQL code string to parse as the table name.
1707                If an `Expression` instance is passed, this is used as-is.
1708            as_: the SQL code string to parse as the table expression.
1709                If an `Expression` instance is passed, it will be used as-is.
1710            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1711            append: if `True`, add to any existing expressions.
1712                Otherwise, this resets the expressions.
1713            dialect: the dialect used to parse the input expression.
1714            copy: if `False`, modify this expression instance in-place.
1715            opts: other options to use to parse the input expressions.
1716
1717        Returns:
1718            The modified expression.
1719        """
1720        return _apply_cte_builder(
1721            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1722        )
arg_types = {'with': 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:
1688    def with_(
1689        self,
1690        alias: ExpOrStr,
1691        as_: ExpOrStr,
1692        recursive: t.Optional[bool] = None,
1693        append: bool = True,
1694        dialect: DialectType = None,
1695        copy: bool = True,
1696        **opts,
1697    ) -> Insert:
1698        """
1699        Append to or set the common table expressions.
1700
1701        Example:
1702            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1703            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1704
1705        Args:
1706            alias: the SQL code string to parse as the table name.
1707                If an `Expression` instance is passed, this is used as-is.
1708            as_: the SQL code string to parse as the table expression.
1709                If an `Expression` instance is passed, it will be used as-is.
1710            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1711            append: if `True`, add to any existing expressions.
1712                Otherwise, this resets the expressions.
1713            dialect: the dialect used to parse the input expression.
1714            copy: if `False`, modify this expression instance in-place.
1715            opts: other options to use to parse the input expressions.
1716
1717        Returns:
1718            The modified expression.
1719        """
1720        return _apply_cte_builder(
1721            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1722        )

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):
1725class OnConflict(Expression):
1726    arg_types = {
1727        "duplicate": False,
1728        "expressions": False,
1729        "nothing": False,
1730        "key": False,
1731        "constraint": False,
1732    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1735class Returning(Expression):
1736    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1740class Introducer(Expression):
1741    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1745class National(Expression):
1746    pass
key = 'national'
class LoadData(Expression):
1749class LoadData(Expression):
1750    arg_types = {
1751        "this": True,
1752        "local": False,
1753        "overwrite": False,
1754        "inpath": True,
1755        "partition": False,
1756        "input_format": False,
1757        "serde": False,
1758    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1761class Partition(Expression):
1762    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1765class Fetch(Expression):
1766    arg_types = {
1767        "direction": False,
1768        "count": False,
1769        "percent": False,
1770        "with_ties": False,
1771    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1774class Group(Expression):
1775    arg_types = {
1776        "expressions": False,
1777        "grouping_sets": False,
1778        "cube": False,
1779        "rollup": False,
1780        "totals": False,
1781        "all": False,
1782    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1785class Lambda(Expression):
1786    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1789class Limit(Expression):
1790    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1793class Literal(Condition):
1794    arg_types = {"this": True, "is_string": True}
1795
1796    @property
1797    def hashable_args(self) -> t.Any:
1798        return (self.this, self.args.get("is_string"))
1799
1800    @classmethod
1801    def number(cls, number) -> Literal:
1802        return cls(this=str(number), is_string=False)
1803
1804    @classmethod
1805    def string(cls, string) -> Literal:
1806        return cls(this=str(string), is_string=True)
1807
1808    @property
1809    def output_name(self) -> str:
1810        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1796    @property
1797    def hashable_args(self) -> t.Any:
1798        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1800    @classmethod
1801    def number(cls, number) -> Literal:
1802        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1804    @classmethod
1805    def string(cls, string) -> Literal:
1806        return cls(this=str(string), is_string=True)
output_name: str
1808    @property
1809    def output_name(self) -> str:
1810        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):
1813class Join(Expression):
1814    arg_types = {
1815        "this": True,
1816        "on": False,
1817        "side": False,
1818        "kind": False,
1819        "using": False,
1820        "method": False,
1821        "global": False,
1822        "hint": False,
1823    }
1824
1825    @property
1826    def method(self) -> str:
1827        return self.text("method").upper()
1828
1829    @property
1830    def kind(self) -> str:
1831        return self.text("kind").upper()
1832
1833    @property
1834    def side(self) -> str:
1835        return self.text("side").upper()
1836
1837    @property
1838    def hint(self) -> str:
1839        return self.text("hint").upper()
1840
1841    @property
1842    def alias_or_name(self) -> str:
1843        return self.this.alias_or_name
1844
1845    def on(
1846        self,
1847        *expressions: t.Optional[ExpOrStr],
1848        append: bool = True,
1849        dialect: DialectType = None,
1850        copy: bool = True,
1851        **opts,
1852    ) -> Join:
1853        """
1854        Append to or set the ON expressions.
1855
1856        Example:
1857            >>> import sqlglot
1858            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1859            'JOIN x ON y = 1'
1860
1861        Args:
1862            *expressions: the SQL code strings to parse.
1863                If an `Expression` instance is passed, it will be used as-is.
1864                Multiple expressions are combined with an AND operator.
1865            append: if `True`, AND the new expressions to any existing expression.
1866                Otherwise, this resets the expression.
1867            dialect: the dialect used to parse the input expressions.
1868            copy: if `False`, modify this expression instance in-place.
1869            opts: other options to use to parse the input expressions.
1870
1871        Returns:
1872            The modified Join expression.
1873        """
1874        join = _apply_conjunction_builder(
1875            *expressions,
1876            instance=self,
1877            arg="on",
1878            append=append,
1879            dialect=dialect,
1880            copy=copy,
1881            **opts,
1882        )
1883
1884        if join.kind == "CROSS":
1885            join.set("kind", None)
1886
1887        return join
1888
1889    def using(
1890        self,
1891        *expressions: t.Optional[ExpOrStr],
1892        append: bool = True,
1893        dialect: DialectType = None,
1894        copy: bool = True,
1895        **opts,
1896    ) -> Join:
1897        """
1898        Append to or set the USING expressions.
1899
1900        Example:
1901            >>> import sqlglot
1902            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1903            'JOIN x USING (foo, bla)'
1904
1905        Args:
1906            *expressions: the SQL code strings to parse.
1907                If an `Expression` instance is passed, it will be used as-is.
1908            append: if `True`, concatenate the new expressions to the existing "using" list.
1909                Otherwise, this resets the expression.
1910            dialect: the dialect used to parse the input expressions.
1911            copy: if `False`, modify this expression instance in-place.
1912            opts: other options to use to parse the input expressions.
1913
1914        Returns:
1915            The modified Join expression.
1916        """
1917        join = _apply_list_builder(
1918            *expressions,
1919            instance=self,
1920            arg="using",
1921            append=append,
1922            dialect=dialect,
1923            copy=copy,
1924            **opts,
1925        )
1926
1927        if join.kind == "CROSS":
1928            join.set("kind", None)
1929
1930        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1825    @property
1826    def method(self) -> str:
1827        return self.text("method").upper()
kind: str
1829    @property
1830    def kind(self) -> str:
1831        return self.text("kind").upper()
side: str
1833    @property
1834    def side(self) -> str:
1835        return self.text("side").upper()
hint: str
1837    @property
1838    def hint(self) -> str:
1839        return self.text("hint").upper()
alias_or_name: str
1841    @property
1842    def alias_or_name(self) -> str:
1843        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:
1845    def on(
1846        self,
1847        *expressions: t.Optional[ExpOrStr],
1848        append: bool = True,
1849        dialect: DialectType = None,
1850        copy: bool = True,
1851        **opts,
1852    ) -> Join:
1853        """
1854        Append to or set the ON expressions.
1855
1856        Example:
1857            >>> import sqlglot
1858            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1859            'JOIN x ON y = 1'
1860
1861        Args:
1862            *expressions: the SQL code strings to parse.
1863                If an `Expression` instance is passed, it will be used as-is.
1864                Multiple expressions are combined with an AND operator.
1865            append: if `True`, AND the new expressions to any existing expression.
1866                Otherwise, this resets the expression.
1867            dialect: the dialect used to parse the input expressions.
1868            copy: if `False`, modify this expression instance in-place.
1869            opts: other options to use to parse the input expressions.
1870
1871        Returns:
1872            The modified Join expression.
1873        """
1874        join = _apply_conjunction_builder(
1875            *expressions,
1876            instance=self,
1877            arg="on",
1878            append=append,
1879            dialect=dialect,
1880            copy=copy,
1881            **opts,
1882        )
1883
1884        if join.kind == "CROSS":
1885            join.set("kind", None)
1886
1887        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:
1889    def using(
1890        self,
1891        *expressions: t.Optional[ExpOrStr],
1892        append: bool = True,
1893        dialect: DialectType = None,
1894        copy: bool = True,
1895        **opts,
1896    ) -> Join:
1897        """
1898        Append to or set the USING expressions.
1899
1900        Example:
1901            >>> import sqlglot
1902            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1903            'JOIN x USING (foo, bla)'
1904
1905        Args:
1906            *expressions: the SQL code strings to parse.
1907                If an `Expression` instance is passed, it will be used as-is.
1908            append: if `True`, concatenate the new expressions to the existing "using" list.
1909                Otherwise, this resets the expression.
1910            dialect: the dialect used to parse the input expressions.
1911            copy: if `False`, modify this expression instance in-place.
1912            opts: other options to use to parse the input expressions.
1913
1914        Returns:
1915            The modified Join expression.
1916        """
1917        join = _apply_list_builder(
1918            *expressions,
1919            instance=self,
1920            arg="using",
1921            append=append,
1922            dialect=dialect,
1923            copy=copy,
1924            **opts,
1925        )
1926
1927        if join.kind == "CROSS":
1928            join.set("kind", None)
1929
1930        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):
1933class Lateral(UDTF):
1934    arg_types = {
1935        "this": True,
1936        "view": False,
1937        "outer": False,
1938        "alias": False,
1939        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1940    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
1943class MatchRecognize(Expression):
1944    arg_types = {
1945        "partition_by": False,
1946        "order": False,
1947        "measures": False,
1948        "rows": False,
1949        "after": False,
1950        "pattern": False,
1951        "define": False,
1952        "alias": False,
1953    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1958class Final(Expression):
1959    pass
key = 'final'
class Offset(Expression):
1962class Offset(Expression):
1963    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1966class Order(Expression):
1967    arg_types = {"this": False, "expressions": True, "interpolate": False}
arg_types = {'this': False, 'expressions': True, 'interpolate': False}
key = 'order'
class WithFill(Expression):
1971class WithFill(Expression):
1972    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
1977class Cluster(Order):
1978    pass
key = 'cluster'
class Distribute(Order):
1981class Distribute(Order):
1982    pass
key = 'distribute'
class Sort(Order):
1985class Sort(Order):
1986    pass
key = 'sort'
class Ordered(Expression):
1989class Ordered(Expression):
1990    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):
1993class Property(Expression):
1994    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
1997class AlgorithmProperty(Property):
1998    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2001class AutoIncrementProperty(Property):
2002    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2006class AutoRefreshProperty(Property):
2007    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2010class BlockCompressionProperty(Property):
2011    arg_types = {"autotemp": False, "always": False, "default": True, "manual": True, "never": True}
arg_types = {'autotemp': False, 'always': False, 'default': True, 'manual': True, 'never': True}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2014class CharacterSetProperty(Property):
2015    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2018class ChecksumProperty(Property):
2019    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2022class CollateProperty(Property):
2023    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2026class CopyGrantsProperty(Property):
2027    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2030class DataBlocksizeProperty(Property):
2031    arg_types = {
2032        "size": False,
2033        "units": False,
2034        "minimum": False,
2035        "maximum": False,
2036        "default": False,
2037    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2040class DefinerProperty(Property):
2041    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2044class DistKeyProperty(Property):
2045    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2048class DistStyleProperty(Property):
2049    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2052class EngineProperty(Property):
2053    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2056class HeapProperty(Property):
2057    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2060class ToTableProperty(Property):
2061    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2064class ExecuteAsProperty(Property):
2065    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2068class ExternalProperty(Property):
2069    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2072class FallbackProperty(Property):
2073    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2076class FileFormatProperty(Property):
2077    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2080class FreespaceProperty(Property):
2081    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InputModelProperty(Property):
2084class InputModelProperty(Property):
2085    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2088class OutputModelProperty(Property):
2089    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2092class IsolatedLoadingProperty(Property):
2093    arg_types = {
2094        "no": True,
2095        "concurrent": True,
2096        "for_all": True,
2097        "for_insert": True,
2098        "for_none": True,
2099    }
arg_types = {'no': True, 'concurrent': True, 'for_all': True, 'for_insert': True, 'for_none': True}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2102class JournalProperty(Property):
2103    arg_types = {
2104        "no": False,
2105        "dual": False,
2106        "before": False,
2107        "local": False,
2108        "after": False,
2109    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2112class LanguageProperty(Property):
2113    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2117class ClusteredByProperty(Property):
2118    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2121class DictProperty(Property):
2122    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2125class DictSubProperty(Property):
2126    pass
key = 'dictsubproperty'
class DictRange(Property):
2129class DictRange(Property):
2130    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2135class OnCluster(Property):
2136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2139class LikeProperty(Property):
2140    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2143class LocationProperty(Property):
2144    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2147class LockingProperty(Property):
2148    arg_types = {
2149        "this": False,
2150        "kind": True,
2151        "for_or_in": False,
2152        "lock_type": True,
2153        "override": False,
2154    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2157class LogProperty(Property):
2158    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2161class MaterializedProperty(Property):
2162    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2165class MergeBlockRatioProperty(Property):
2166    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):
2169class NoPrimaryIndexProperty(Property):
2170    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2173class OnProperty(Property):
2174    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2177class OnCommitProperty(Property):
2178    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2181class PartitionedByProperty(Property):
2182    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2186class PartitionBoundSpec(Expression):
2187    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2188    arg_types = {
2189        "this": False,
2190        "expression": False,
2191        "from_expressions": False,
2192        "to_expressions": False,
2193    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2196class PartitionedOfProperty(Property):
2197    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2198    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2201class RemoteWithConnectionModelProperty(Property):
2202    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2205class ReturnsProperty(Property):
2206    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2209class RowFormatProperty(Property):
2210    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2213class RowFormatDelimitedProperty(Property):
2214    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2215    arg_types = {
2216        "fields": False,
2217        "escaped": False,
2218        "collection_items": False,
2219        "map_keys": False,
2220        "lines": False,
2221        "null": False,
2222        "serde": False,
2223    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2226class RowFormatSerdeProperty(Property):
2227    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2231class QueryTransform(Expression):
2232    arg_types = {
2233        "expressions": True,
2234        "command_script": True,
2235        "schema": False,
2236        "row_format_before": False,
2237        "record_writer": False,
2238        "row_format_after": False,
2239        "record_reader": False,
2240    }
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):
2243class SampleProperty(Property):
2244    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2247class SchemaCommentProperty(Property):
2248    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2251class SerdeProperties(Property):
2252    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2255class SetProperty(Property):
2256    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SettingsProperty(Property):
2259class SettingsProperty(Property):
2260    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2263class SortKeyProperty(Property):
2264    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2267class SqlReadWriteProperty(Property):
2268    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2271class SqlSecurityProperty(Property):
2272    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2275class StabilityProperty(Property):
2276    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2279class TemporaryProperty(Property):
2280    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2283class TransformModelProperty(Property):
2284    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2287class TransientProperty(Property):
2288    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2291class VolatileProperty(Property):
2292    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2295class WithDataProperty(Property):
2296    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2299class WithJournalTableProperty(Property):
2300    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2303class WithSystemVersioningProperty(Property):
2304    # this -> history table name, expression -> data consistency check
2305    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2308class Properties(Expression):
2309    arg_types = {"expressions": True}
2310
2311    NAME_TO_PROPERTY = {
2312        "ALGORITHM": AlgorithmProperty,
2313        "AUTO_INCREMENT": AutoIncrementProperty,
2314        "CHARACTER SET": CharacterSetProperty,
2315        "CLUSTERED_BY": ClusteredByProperty,
2316        "COLLATE": CollateProperty,
2317        "COMMENT": SchemaCommentProperty,
2318        "DEFINER": DefinerProperty,
2319        "DISTKEY": DistKeyProperty,
2320        "DISTSTYLE": DistStyleProperty,
2321        "ENGINE": EngineProperty,
2322        "EXECUTE AS": ExecuteAsProperty,
2323        "FORMAT": FileFormatProperty,
2324        "LANGUAGE": LanguageProperty,
2325        "LOCATION": LocationProperty,
2326        "PARTITIONED_BY": PartitionedByProperty,
2327        "RETURNS": ReturnsProperty,
2328        "ROW_FORMAT": RowFormatProperty,
2329        "SORTKEY": SortKeyProperty,
2330    }
2331
2332    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2333
2334    # CREATE property locations
2335    # Form: schema specified
2336    #   create [POST_CREATE]
2337    #     table a [POST_NAME]
2338    #     (b int) [POST_SCHEMA]
2339    #     with ([POST_WITH])
2340    #     index (b) [POST_INDEX]
2341    #
2342    # Form: alias selection
2343    #   create [POST_CREATE]
2344    #     table a [POST_NAME]
2345    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2346    #     index (c) [POST_INDEX]
2347    class Location(AutoName):
2348        POST_CREATE = auto()
2349        POST_NAME = auto()
2350        POST_SCHEMA = auto()
2351        POST_WITH = auto()
2352        POST_ALIAS = auto()
2353        POST_EXPRESSION = auto()
2354        POST_INDEX = auto()
2355        UNSUPPORTED = auto()
2356
2357    @classmethod
2358    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2359        expressions = []
2360        for key, value in properties_dict.items():
2361            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2362            if property_cls:
2363                expressions.append(property_cls(this=convert(value)))
2364            else:
2365                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2366
2367        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'>, '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 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2357    @classmethod
2358    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2359        expressions = []
2360        for key, value in properties_dict.items():
2361            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2362            if property_cls:
2363                expressions.append(property_cls(this=convert(value)))
2364            else:
2365                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2366
2367        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2347    class Location(AutoName):
2348        POST_CREATE = auto()
2349        POST_NAME = auto()
2350        POST_SCHEMA = auto()
2351        POST_WITH = auto()
2352        POST_ALIAS = auto()
2353        POST_EXPRESSION = auto()
2354        POST_INDEX = auto()
2355        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):
2370class Qualify(Expression):
2371    pass
key = 'qualify'
class InputOutputFormat(Expression):
2374class InputOutputFormat(Expression):
2375    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2379class Return(Expression):
2380    pass
key = 'return'
class Reference(Expression):
2383class Reference(Expression):
2384    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2387class Tuple(Expression):
2388    arg_types = {"expressions": False}
2389
2390    def isin(
2391        self,
2392        *expressions: t.Any,
2393        query: t.Optional[ExpOrStr] = None,
2394        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2395        copy: bool = True,
2396        **opts,
2397    ) -> In:
2398        return In(
2399            this=maybe_copy(self, copy),
2400            expressions=[convert(e, copy=copy) for e in expressions],
2401            query=maybe_parse(query, copy=copy, **opts) if query else None,
2402            unnest=Unnest(
2403                expressions=[
2404                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2405                ]
2406            )
2407            if unnest
2408            else None,
2409        )
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:
2390    def isin(
2391        self,
2392        *expressions: t.Any,
2393        query: t.Optional[ExpOrStr] = None,
2394        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2395        copy: bool = True,
2396        **opts,
2397    ) -> In:
2398        return In(
2399            this=maybe_copy(self, copy),
2400            expressions=[convert(e, copy=copy) for e in expressions],
2401            query=maybe_parse(query, copy=copy, **opts) if query else None,
2402            unnest=Unnest(
2403                expressions=[
2404                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2405                ]
2406            )
2407            if unnest
2408            else None,
2409        )
key = 'tuple'
class Subqueryable(Unionable):
2412class Subqueryable(Unionable):
2413    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2414        """
2415        Convert this expression to an aliased expression that can be used as a Subquery.
2416
2417        Example:
2418            >>> subquery = Select().select("x").from_("tbl").subquery()
2419            >>> Select().select("x").from_(subquery).sql()
2420            'SELECT x FROM (SELECT x FROM tbl)'
2421
2422        Args:
2423            alias (str | Identifier): an optional alias for the subquery
2424            copy (bool): if `False`, modify this expression instance in-place.
2425
2426        Returns:
2427            Alias: the subquery
2428        """
2429        instance = maybe_copy(self, copy)
2430        if not isinstance(alias, Expression):
2431            alias = TableAlias(this=to_identifier(alias)) if alias else None
2432
2433        return Subquery(this=instance, alias=alias)
2434
2435    def limit(
2436        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2437    ) -> Select:
2438        raise NotImplementedError
2439
2440    @property
2441    def ctes(self):
2442        with_ = self.args.get("with")
2443        if not with_:
2444            return []
2445        return with_.expressions
2446
2447    @property
2448    def selects(self) -> t.List[Expression]:
2449        raise NotImplementedError("Subqueryable objects must implement `selects`")
2450
2451    @property
2452    def named_selects(self) -> t.List[str]:
2453        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2454
2455    def select(
2456        self,
2457        *expressions: t.Optional[ExpOrStr],
2458        append: bool = True,
2459        dialect: DialectType = None,
2460        copy: bool = True,
2461        **opts,
2462    ) -> Subqueryable:
2463        raise NotImplementedError("Subqueryable objects must implement `select`")
2464
2465    def with_(
2466        self,
2467        alias: ExpOrStr,
2468        as_: ExpOrStr,
2469        recursive: t.Optional[bool] = None,
2470        append: bool = True,
2471        dialect: DialectType = None,
2472        copy: bool = True,
2473        **opts,
2474    ) -> Subqueryable:
2475        """
2476        Append to or set the common table expressions.
2477
2478        Example:
2479            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2480            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2481
2482        Args:
2483            alias: the SQL code string to parse as the table name.
2484                If an `Expression` instance is passed, this is used as-is.
2485            as_: the SQL code string to parse as the table expression.
2486                If an `Expression` instance is passed, it will be used as-is.
2487            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2488            append: if `True`, add to any existing expressions.
2489                Otherwise, this resets the expressions.
2490            dialect: the dialect used to parse the input expression.
2491            copy: if `False`, modify this expression instance in-place.
2492            opts: other options to use to parse the input expressions.
2493
2494        Returns:
2495            The modified expression.
2496        """
2497        return _apply_cte_builder(
2498            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2499        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2413    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2414        """
2415        Convert this expression to an aliased expression that can be used as a Subquery.
2416
2417        Example:
2418            >>> subquery = Select().select("x").from_("tbl").subquery()
2419            >>> Select().select("x").from_(subquery).sql()
2420            'SELECT x FROM (SELECT x FROM tbl)'
2421
2422        Args:
2423            alias (str | Identifier): an optional alias for the subquery
2424            copy (bool): if `False`, modify this expression instance in-place.
2425
2426        Returns:
2427            Alias: the subquery
2428        """
2429        instance = maybe_copy(self, copy)
2430        if not isinstance(alias, Expression):
2431            alias = TableAlias(this=to_identifier(alias)) if alias else None
2432
2433        return Subquery(this=instance, alias=alias)

Convert this expression to an aliased expression that can be used as a Subquery.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias (str | Identifier): an optional alias for the subquery
  • copy (bool): if False, modify this expression instance in-place.
Returns:

Alias: the subquery

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:
2435    def limit(
2436        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2437    ) -> Select:
2438        raise NotImplementedError
ctes
2440    @property
2441    def ctes(self):
2442        with_ = self.args.get("with")
2443        if not with_:
2444            return []
2445        return with_.expressions
selects: List[Expression]
2447    @property
2448    def selects(self) -> t.List[Expression]:
2449        raise NotImplementedError("Subqueryable objects must implement `selects`")
named_selects: List[str]
2451    @property
2452    def named_selects(self) -> t.List[str]:
2453        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
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) -> Subqueryable:
2455    def select(
2456        self,
2457        *expressions: t.Optional[ExpOrStr],
2458        append: bool = True,
2459        dialect: DialectType = None,
2460        copy: bool = True,
2461        **opts,
2462    ) -> Subqueryable:
2463        raise NotImplementedError("Subqueryable objects must implement `select`")
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) -> Subqueryable:
2465    def with_(
2466        self,
2467        alias: ExpOrStr,
2468        as_: ExpOrStr,
2469        recursive: t.Optional[bool] = None,
2470        append: bool = True,
2471        dialect: DialectType = None,
2472        copy: bool = True,
2473        **opts,
2474    ) -> Subqueryable:
2475        """
2476        Append to or set the common table expressions.
2477
2478        Example:
2479            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2480            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2481
2482        Args:
2483            alias: the SQL code string to parse as the table name.
2484                If an `Expression` instance is passed, this is used as-is.
2485            as_: the SQL code string to parse as the table expression.
2486                If an `Expression` instance is passed, it will be used as-is.
2487            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2488            append: if `True`, add to any existing expressions.
2489                Otherwise, this resets the expressions.
2490            dialect: the dialect used to parse the input expression.
2491            copy: if `False`, modify this expression instance in-place.
2492            opts: other options to use to parse the input expressions.
2493
2494        Returns:
2495            The modified expression.
2496        """
2497        return _apply_cte_builder(
2498            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2499        )

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.

key = 'subqueryable'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
class WithTableHint(Expression):
2527class WithTableHint(Expression):
2528    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2532class IndexTableHint(Expression):
2533    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2537class HistoricalData(Expression):
2538    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2541class Table(Expression):
2542    arg_types = {
2543        "this": True,
2544        "alias": False,
2545        "db": False,
2546        "catalog": False,
2547        "laterals": False,
2548        "joins": False,
2549        "pivots": False,
2550        "hints": False,
2551        "system_time": False,
2552        "version": False,
2553        "format": False,
2554        "pattern": False,
2555        "ordinality": False,
2556        "when": False,
2557    }
2558
2559    @property
2560    def name(self) -> str:
2561        if isinstance(self.this, Func):
2562            return ""
2563        return self.this.name
2564
2565    @property
2566    def db(self) -> str:
2567        return self.text("db")
2568
2569    @property
2570    def catalog(self) -> str:
2571        return self.text("catalog")
2572
2573    @property
2574    def selects(self) -> t.List[Expression]:
2575        return []
2576
2577    @property
2578    def named_selects(self) -> t.List[str]:
2579        return []
2580
2581    @property
2582    def parts(self) -> t.List[Expression]:
2583        """Return the parts of a table in order catalog, db, table."""
2584        parts: t.List[Expression] = []
2585
2586        for arg in ("catalog", "db", "this"):
2587            part = self.args.get(arg)
2588
2589            if isinstance(part, Dot):
2590                parts.extend(part.flatten())
2591            elif isinstance(part, Expression):
2592                parts.append(part)
2593
2594        return parts
2595
2596    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2597        parts = self.parts
2598        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2599        alias = self.args.get("alias")
2600        if alias:
2601            col = alias_(col, alias.this, copy=copy)
2602        return col
arg_types = {'this': True, '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}
name: str
2559    @property
2560    def name(self) -> str:
2561        if isinstance(self.this, Func):
2562            return ""
2563        return self.this.name
db: str
2565    @property
2566    def db(self) -> str:
2567        return self.text("db")
catalog: str
2569    @property
2570    def catalog(self) -> str:
2571        return self.text("catalog")
selects: List[Expression]
2573    @property
2574    def selects(self) -> t.List[Expression]:
2575        return []
named_selects: List[str]
2577    @property
2578    def named_selects(self) -> t.List[str]:
2579        return []
parts: List[Expression]
2581    @property
2582    def parts(self) -> t.List[Expression]:
2583        """Return the parts of a table in order catalog, db, table."""
2584        parts: t.List[Expression] = []
2585
2586        for arg in ("catalog", "db", "this"):
2587            part = self.args.get(arg)
2588
2589            if isinstance(part, Dot):
2590                parts.extend(part.flatten())
2591            elif isinstance(part, Expression):
2592                parts.append(part)
2593
2594        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2596    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2597        parts = self.parts
2598        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2599        alias = self.args.get("alias")
2600        if alias:
2601            col = alias_(col, alias.this, copy=copy)
2602        return col
key = 'table'
class Union(Subqueryable):
2605class Union(Subqueryable):
2606    arg_types = {
2607        "with": False,
2608        "this": True,
2609        "expression": True,
2610        "distinct": False,
2611        "by_name": False,
2612        **QUERY_MODIFIERS,
2613    }
2614
2615    def limit(
2616        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2617    ) -> Select:
2618        """
2619        Set the LIMIT expression.
2620
2621        Example:
2622            >>> select("1").union(select("1")).limit(1).sql()
2623            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2624
2625        Args:
2626            expression: the SQL code string to parse.
2627                This can also be an integer.
2628                If a `Limit` instance is passed, this is used as-is.
2629                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2630            dialect: the dialect used to parse the input expression.
2631            copy: if `False`, modify this expression instance in-place.
2632            opts: other options to use to parse the input expressions.
2633
2634        Returns:
2635            The limited subqueryable.
2636        """
2637        return (
2638            select("*")
2639            .from_(self.subquery(alias="_l_0", copy=copy))
2640            .limit(expression, dialect=dialect, copy=False, **opts)
2641        )
2642
2643    def select(
2644        self,
2645        *expressions: t.Optional[ExpOrStr],
2646        append: bool = True,
2647        dialect: DialectType = None,
2648        copy: bool = True,
2649        **opts,
2650    ) -> Union:
2651        """Append to or set the SELECT of the union recursively.
2652
2653        Example:
2654            >>> from sqlglot import parse_one
2655            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2656            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2657
2658        Args:
2659            *expressions: the SQL code strings to parse.
2660                If an `Expression` instance is passed, it will be used as-is.
2661            append: if `True`, add to any existing expressions.
2662                Otherwise, this resets the expressions.
2663            dialect: the dialect used to parse the input expressions.
2664            copy: if `False`, modify this expression instance in-place.
2665            opts: other options to use to parse the input expressions.
2666
2667        Returns:
2668            Union: the modified expression.
2669        """
2670        this = self.copy() if copy else self
2671        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2672        this.expression.unnest().select(
2673            *expressions, append=append, dialect=dialect, copy=False, **opts
2674        )
2675        return this
2676
2677    @property
2678    def named_selects(self) -> t.List[str]:
2679        return self.this.unnest().named_selects
2680
2681    @property
2682    def is_star(self) -> bool:
2683        return self.this.is_star or self.expression.is_star
2684
2685    @property
2686    def selects(self) -> t.List[Expression]:
2687        return self.this.unnest().selects
2688
2689    @property
2690    def left(self) -> Expression:
2691        return self.this
2692
2693    @property
2694    def right(self) -> Expression:
2695        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, '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}
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:
2615    def limit(
2616        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2617    ) -> Select:
2618        """
2619        Set the LIMIT expression.
2620
2621        Example:
2622            >>> select("1").union(select("1")).limit(1).sql()
2623            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2624
2625        Args:
2626            expression: the SQL code string to parse.
2627                This can also be an integer.
2628                If a `Limit` instance is passed, this is used as-is.
2629                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2630            dialect: the dialect used to parse the input expression.
2631            copy: if `False`, modify this expression instance in-place.
2632            opts: other options to use to parse the input expressions.
2633
2634        Returns:
2635            The limited subqueryable.
2636        """
2637        return (
2638            select("*")
2639            .from_(self.subquery(alias="_l_0", copy=copy))
2640            .limit(expression, dialect=dialect, copy=False, **opts)
2641        )

Set the LIMIT expression.

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, this is 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:

The limited subqueryable.

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:
2643    def select(
2644        self,
2645        *expressions: t.Optional[ExpOrStr],
2646        append: bool = True,
2647        dialect: DialectType = None,
2648        copy: bool = True,
2649        **opts,
2650    ) -> Union:
2651        """Append to or set the SELECT of the union recursively.
2652
2653        Example:
2654            >>> from sqlglot import parse_one
2655            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2656            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2657
2658        Args:
2659            *expressions: the SQL code strings to parse.
2660                If an `Expression` instance is passed, it will be used as-is.
2661            append: if `True`, add to any existing expressions.
2662                Otherwise, this resets the expressions.
2663            dialect: the dialect used to parse the input expressions.
2664            copy: if `False`, modify this expression instance in-place.
2665            opts: other options to use to parse the input expressions.
2666
2667        Returns:
2668            Union: the modified expression.
2669        """
2670        this = self.copy() if copy else self
2671        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2672        this.expression.unnest().select(
2673            *expressions, append=append, dialect=dialect, copy=False, **opts
2674        )
2675        return this

Append to or set the SELECT of the union recursively.

Example:
>>> from sqlglot import parse_one
>>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM 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:

Union: the modified expression.

named_selects: List[str]
2677    @property
2678    def named_selects(self) -> t.List[str]:
2679        return self.this.unnest().named_selects
is_star: bool
2681    @property
2682    def is_star(self) -> bool:
2683        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2685    @property
2686    def selects(self) -> t.List[Expression]:
2687        return self.this.unnest().selects
left: Expression
2689    @property
2690    def left(self) -> Expression:
2691        return self.this
right: Expression
2693    @property
2694    def right(self) -> Expression:
2695        return self.expression
key = 'union'
class Except(Union):
2698class Except(Union):
2699    pass
key = 'except'
class Intersect(Union):
2702class Intersect(Union):
2703    pass
key = 'intersect'
class Unnest(UDTF):
2706class Unnest(UDTF):
2707    arg_types = {
2708        "expressions": True,
2709        "alias": False,
2710        "offset": False,
2711    }
arg_types = {'expressions': True, 'alias': False, 'offset': False}
key = 'unnest'
class Update(Expression):
2714class Update(Expression):
2715    arg_types = {
2716        "with": False,
2717        "this": False,
2718        "expressions": True,
2719        "from": False,
2720        "where": False,
2721        "returning": False,
2722        "order": False,
2723        "limit": False,
2724    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
2727class Values(UDTF):
2728    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
2731class Var(Expression):
2732    pass
key = 'var'
class Version(Expression):
2735class Version(Expression):
2736    """
2737    Time travel, iceberg, bigquery etc
2738    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2739    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2740    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2741    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2742    this is either TIMESTAMP or VERSION
2743    kind is ("AS OF", "BETWEEN")
2744    """
2745
2746    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
2749class Schema(Expression):
2750    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
2755class Lock(Expression):
2756    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Subqueryable):
2759class Select(Subqueryable):
2760    arg_types = {
2761        "with": False,
2762        "kind": False,
2763        "expressions": False,
2764        "hint": False,
2765        "distinct": False,
2766        "into": False,
2767        "from": False,
2768        **QUERY_MODIFIERS,
2769    }
2770
2771    def from_(
2772        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2773    ) -> Select:
2774        """
2775        Set the FROM expression.
2776
2777        Example:
2778            >>> Select().from_("tbl").select("x").sql()
2779            'SELECT x FROM tbl'
2780
2781        Args:
2782            expression : the SQL code strings to parse.
2783                If a `From` instance is passed, this is used as-is.
2784                If another `Expression` instance is passed, it will be wrapped in a `From`.
2785            dialect: the dialect used to parse the input expression.
2786            copy: if `False`, modify this expression instance in-place.
2787            opts: other options to use to parse the input expressions.
2788
2789        Returns:
2790            The modified Select expression.
2791        """
2792        return _apply_builder(
2793            expression=expression,
2794            instance=self,
2795            arg="from",
2796            into=From,
2797            prefix="FROM",
2798            dialect=dialect,
2799            copy=copy,
2800            **opts,
2801        )
2802
2803    def group_by(
2804        self,
2805        *expressions: t.Optional[ExpOrStr],
2806        append: bool = True,
2807        dialect: DialectType = None,
2808        copy: bool = True,
2809        **opts,
2810    ) -> Select:
2811        """
2812        Set the GROUP BY expression.
2813
2814        Example:
2815            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2816            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2817
2818        Args:
2819            *expressions: the SQL code strings to parse.
2820                If a `Group` instance is passed, this is used as-is.
2821                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2822                If nothing is passed in then a group by is not applied to the expression
2823            append: if `True`, add to any existing expressions.
2824                Otherwise, this flattens all the `Group` expression into a single expression.
2825            dialect: the dialect used to parse the input expression.
2826            copy: if `False`, modify this expression instance in-place.
2827            opts: other options to use to parse the input expressions.
2828
2829        Returns:
2830            The modified Select expression.
2831        """
2832        if not expressions:
2833            return self if not copy else self.copy()
2834
2835        return _apply_child_list_builder(
2836            *expressions,
2837            instance=self,
2838            arg="group",
2839            append=append,
2840            copy=copy,
2841            prefix="GROUP BY",
2842            into=Group,
2843            dialect=dialect,
2844            **opts,
2845        )
2846
2847    def order_by(
2848        self,
2849        *expressions: t.Optional[ExpOrStr],
2850        append: bool = True,
2851        dialect: DialectType = None,
2852        copy: bool = True,
2853        **opts,
2854    ) -> Select:
2855        """
2856        Set the ORDER BY expression.
2857
2858        Example:
2859            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2860            'SELECT x FROM tbl ORDER BY x DESC'
2861
2862        Args:
2863            *expressions: the SQL code strings to parse.
2864                If a `Group` instance is passed, this is used as-is.
2865                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2866            append: if `True`, add to any existing expressions.
2867                Otherwise, this flattens all the `Order` expression into a single expression.
2868            dialect: the dialect used to parse the input expression.
2869            copy: if `False`, modify this expression instance in-place.
2870            opts: other options to use to parse the input expressions.
2871
2872        Returns:
2873            The modified Select expression.
2874        """
2875        return _apply_child_list_builder(
2876            *expressions,
2877            instance=self,
2878            arg="order",
2879            append=append,
2880            copy=copy,
2881            prefix="ORDER BY",
2882            into=Order,
2883            dialect=dialect,
2884            **opts,
2885        )
2886
2887    def sort_by(
2888        self,
2889        *expressions: t.Optional[ExpOrStr],
2890        append: bool = True,
2891        dialect: DialectType = None,
2892        copy: bool = True,
2893        **opts,
2894    ) -> Select:
2895        """
2896        Set the SORT BY expression.
2897
2898        Example:
2899            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2900            'SELECT x FROM tbl SORT BY x DESC'
2901
2902        Args:
2903            *expressions: the SQL code strings to parse.
2904                If a `Group` instance is passed, this is used as-is.
2905                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2906            append: if `True`, add to any existing expressions.
2907                Otherwise, this flattens all the `Order` expression into a single expression.
2908            dialect: the dialect used to parse the input expression.
2909            copy: if `False`, modify this expression instance in-place.
2910            opts: other options to use to parse the input expressions.
2911
2912        Returns:
2913            The modified Select expression.
2914        """
2915        return _apply_child_list_builder(
2916            *expressions,
2917            instance=self,
2918            arg="sort",
2919            append=append,
2920            copy=copy,
2921            prefix="SORT BY",
2922            into=Sort,
2923            dialect=dialect,
2924            **opts,
2925        )
2926
2927    def cluster_by(
2928        self,
2929        *expressions: t.Optional[ExpOrStr],
2930        append: bool = True,
2931        dialect: DialectType = None,
2932        copy: bool = True,
2933        **opts,
2934    ) -> Select:
2935        """
2936        Set the CLUSTER BY expression.
2937
2938        Example:
2939            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2940            'SELECT x FROM tbl CLUSTER BY x DESC'
2941
2942        Args:
2943            *expressions: the SQL code strings to parse.
2944                If a `Group` instance is passed, this is used as-is.
2945                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2946            append: if `True`, add to any existing expressions.
2947                Otherwise, this flattens all the `Order` expression into a single expression.
2948            dialect: the dialect used to parse the input expression.
2949            copy: if `False`, modify this expression instance in-place.
2950            opts: other options to use to parse the input expressions.
2951
2952        Returns:
2953            The modified Select expression.
2954        """
2955        return _apply_child_list_builder(
2956            *expressions,
2957            instance=self,
2958            arg="cluster",
2959            append=append,
2960            copy=copy,
2961            prefix="CLUSTER BY",
2962            into=Cluster,
2963            dialect=dialect,
2964            **opts,
2965        )
2966
2967    def limit(
2968        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2969    ) -> Select:
2970        """
2971        Set the LIMIT expression.
2972
2973        Example:
2974            >>> Select().from_("tbl").select("x").limit(10).sql()
2975            'SELECT x FROM tbl LIMIT 10'
2976
2977        Args:
2978            expression: the SQL code string to parse.
2979                This can also be an integer.
2980                If a `Limit` instance is passed, this is used as-is.
2981                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
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            Select: the modified expression.
2988        """
2989        return _apply_builder(
2990            expression=expression,
2991            instance=self,
2992            arg="limit",
2993            into=Limit,
2994            prefix="LIMIT",
2995            dialect=dialect,
2996            copy=copy,
2997            into_arg="expression",
2998            **opts,
2999        )
3000
3001    def offset(
3002        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3003    ) -> Select:
3004        """
3005        Set the OFFSET expression.
3006
3007        Example:
3008            >>> Select().from_("tbl").select("x").offset(10).sql()
3009            'SELECT x FROM tbl OFFSET 10'
3010
3011        Args:
3012            expression: the SQL code string to parse.
3013                This can also be an integer.
3014                If a `Offset` instance is passed, this is used as-is.
3015                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3016            dialect: the dialect used to parse the input expression.
3017            copy: if `False`, modify this expression instance in-place.
3018            opts: other options to use to parse the input expressions.
3019
3020        Returns:
3021            The modified Select expression.
3022        """
3023        return _apply_builder(
3024            expression=expression,
3025            instance=self,
3026            arg="offset",
3027            into=Offset,
3028            prefix="OFFSET",
3029            dialect=dialect,
3030            copy=copy,
3031            into_arg="expression",
3032            **opts,
3033        )
3034
3035    def select(
3036        self,
3037        *expressions: t.Optional[ExpOrStr],
3038        append: bool = True,
3039        dialect: DialectType = None,
3040        copy: bool = True,
3041        **opts,
3042    ) -> Select:
3043        """
3044        Append to or set the SELECT expressions.
3045
3046        Example:
3047            >>> Select().select("x", "y").sql()
3048            'SELECT x, y'
3049
3050        Args:
3051            *expressions: the SQL code strings to parse.
3052                If an `Expression` instance is passed, it will be used as-is.
3053            append: if `True`, add to any existing expressions.
3054                Otherwise, this resets the expressions.
3055            dialect: the dialect used to parse the input expressions.
3056            copy: if `False`, modify this expression instance in-place.
3057            opts: other options to use to parse the input expressions.
3058
3059        Returns:
3060            The modified Select expression.
3061        """
3062        return _apply_list_builder(
3063            *expressions,
3064            instance=self,
3065            arg="expressions",
3066            append=append,
3067            dialect=dialect,
3068            copy=copy,
3069            **opts,
3070        )
3071
3072    def lateral(
3073        self,
3074        *expressions: t.Optional[ExpOrStr],
3075        append: bool = True,
3076        dialect: DialectType = None,
3077        copy: bool = True,
3078        **opts,
3079    ) -> Select:
3080        """
3081        Append to or set the LATERAL expressions.
3082
3083        Example:
3084            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3085            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3086
3087        Args:
3088            *expressions: the SQL code strings to parse.
3089                If an `Expression` instance is passed, it will be used as-is.
3090            append: if `True`, add to any existing expressions.
3091                Otherwise, this resets the expressions.
3092            dialect: the dialect used to parse the input expressions.
3093            copy: if `False`, modify this expression instance in-place.
3094            opts: other options to use to parse the input expressions.
3095
3096        Returns:
3097            The modified Select expression.
3098        """
3099        return _apply_list_builder(
3100            *expressions,
3101            instance=self,
3102            arg="laterals",
3103            append=append,
3104            into=Lateral,
3105            prefix="LATERAL VIEW",
3106            dialect=dialect,
3107            copy=copy,
3108            **opts,
3109        )
3110
3111    def join(
3112        self,
3113        expression: ExpOrStr,
3114        on: t.Optional[ExpOrStr] = None,
3115        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3116        append: bool = True,
3117        join_type: t.Optional[str] = None,
3118        join_alias: t.Optional[Identifier | str] = None,
3119        dialect: DialectType = None,
3120        copy: bool = True,
3121        **opts,
3122    ) -> Select:
3123        """
3124        Append to or set the JOIN expressions.
3125
3126        Example:
3127            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3128            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3129
3130            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3131            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3132
3133            Use `join_type` to change the type of join:
3134
3135            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3136            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3137
3138        Args:
3139            expression: the SQL code string to parse.
3140                If an `Expression` instance is passed, it will be used as-is.
3141            on: optionally specify the join "on" criteria as a SQL string.
3142                If an `Expression` instance is passed, it will be used as-is.
3143            using: optionally specify the join "using" criteria as a SQL string.
3144                If an `Expression` instance is passed, it will be used as-is.
3145            append: if `True`, add to any existing expressions.
3146                Otherwise, this resets the expressions.
3147            join_type: if set, alter the parsed join type.
3148            join_alias: an optional alias for the joined source.
3149            dialect: the dialect used to parse the input expressions.
3150            copy: if `False`, modify this expression instance in-place.
3151            opts: other options to use to parse the input expressions.
3152
3153        Returns:
3154            Select: the modified expression.
3155        """
3156        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3157
3158        try:
3159            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3160        except ParseError:
3161            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3162
3163        join = expression if isinstance(expression, Join) else Join(this=expression)
3164
3165        if isinstance(join.this, Select):
3166            join.this.replace(join.this.subquery())
3167
3168        if join_type:
3169            method: t.Optional[Token]
3170            side: t.Optional[Token]
3171            kind: t.Optional[Token]
3172
3173            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3174
3175            if method:
3176                join.set("method", method.text)
3177            if side:
3178                join.set("side", side.text)
3179            if kind:
3180                join.set("kind", kind.text)
3181
3182        if on:
3183            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3184            join.set("on", on)
3185
3186        if using:
3187            join = _apply_list_builder(
3188                *ensure_list(using),
3189                instance=join,
3190                arg="using",
3191                append=append,
3192                copy=copy,
3193                into=Identifier,
3194                **opts,
3195            )
3196
3197        if join_alias:
3198            join.set("this", alias_(join.this, join_alias, table=True))
3199
3200        return _apply_list_builder(
3201            join,
3202            instance=self,
3203            arg="joins",
3204            append=append,
3205            copy=copy,
3206            **opts,
3207        )
3208
3209    def where(
3210        self,
3211        *expressions: t.Optional[ExpOrStr],
3212        append: bool = True,
3213        dialect: DialectType = None,
3214        copy: bool = True,
3215        **opts,
3216    ) -> Select:
3217        """
3218        Append to or set the WHERE expressions.
3219
3220        Example:
3221            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3222            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3223
3224        Args:
3225            *expressions: the SQL code strings to parse.
3226                If an `Expression` instance is passed, it will be used as-is.
3227                Multiple expressions are combined with an AND operator.
3228            append: if `True`, AND the new expressions to any existing expression.
3229                Otherwise, this resets the expression.
3230            dialect: the dialect used to parse the input expressions.
3231            copy: if `False`, modify this expression instance in-place.
3232            opts: other options to use to parse the input expressions.
3233
3234        Returns:
3235            Select: the modified expression.
3236        """
3237        return _apply_conjunction_builder(
3238            *expressions,
3239            instance=self,
3240            arg="where",
3241            append=append,
3242            into=Where,
3243            dialect=dialect,
3244            copy=copy,
3245            **opts,
3246        )
3247
3248    def having(
3249        self,
3250        *expressions: t.Optional[ExpOrStr],
3251        append: bool = True,
3252        dialect: DialectType = None,
3253        copy: bool = True,
3254        **opts,
3255    ) -> Select:
3256        """
3257        Append to or set the HAVING expressions.
3258
3259        Example:
3260            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3261            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3262
3263        Args:
3264            *expressions: the SQL code strings to parse.
3265                If an `Expression` instance is passed, it will be used as-is.
3266                Multiple expressions are combined with an AND operator.
3267            append: if `True`, AND the new expressions to any existing expression.
3268                Otherwise, this resets the expression.
3269            dialect: the dialect used to parse the input expressions.
3270            copy: if `False`, modify this expression instance in-place.
3271            opts: other options to use to parse the input expressions.
3272
3273        Returns:
3274            The modified Select expression.
3275        """
3276        return _apply_conjunction_builder(
3277            *expressions,
3278            instance=self,
3279            arg="having",
3280            append=append,
3281            into=Having,
3282            dialect=dialect,
3283            copy=copy,
3284            **opts,
3285        )
3286
3287    def window(
3288        self,
3289        *expressions: t.Optional[ExpOrStr],
3290        append: bool = True,
3291        dialect: DialectType = None,
3292        copy: bool = True,
3293        **opts,
3294    ) -> Select:
3295        return _apply_list_builder(
3296            *expressions,
3297            instance=self,
3298            arg="windows",
3299            append=append,
3300            into=Window,
3301            dialect=dialect,
3302            copy=copy,
3303            **opts,
3304        )
3305
3306    def qualify(
3307        self,
3308        *expressions: t.Optional[ExpOrStr],
3309        append: bool = True,
3310        dialect: DialectType = None,
3311        copy: bool = True,
3312        **opts,
3313    ) -> Select:
3314        return _apply_conjunction_builder(
3315            *expressions,
3316            instance=self,
3317            arg="qualify",
3318            append=append,
3319            into=Qualify,
3320            dialect=dialect,
3321            copy=copy,
3322            **opts,
3323        )
3324
3325    def distinct(
3326        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3327    ) -> Select:
3328        """
3329        Set the OFFSET expression.
3330
3331        Example:
3332            >>> Select().from_("tbl").select("x").distinct().sql()
3333            'SELECT DISTINCT x FROM tbl'
3334
3335        Args:
3336            ons: the expressions to distinct on
3337            distinct: whether the Select should be distinct
3338            copy: if `False`, modify this expression instance in-place.
3339
3340        Returns:
3341            Select: the modified expression.
3342        """
3343        instance = maybe_copy(self, copy)
3344        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3345        instance.set("distinct", Distinct(on=on) if distinct else None)
3346        return instance
3347
3348    def ctas(
3349        self,
3350        table: ExpOrStr,
3351        properties: t.Optional[t.Dict] = None,
3352        dialect: DialectType = None,
3353        copy: bool = True,
3354        **opts,
3355    ) -> Create:
3356        """
3357        Convert this expression to a CREATE TABLE AS statement.
3358
3359        Example:
3360            >>> Select().select("*").from_("tbl").ctas("x").sql()
3361            'CREATE TABLE x AS SELECT * FROM tbl'
3362
3363        Args:
3364            table: the SQL code string to parse as the table name.
3365                If another `Expression` instance is passed, it will be used as-is.
3366            properties: an optional mapping of table properties
3367            dialect: the dialect used to parse the input table.
3368            copy: if `False`, modify this expression instance in-place.
3369            opts: other options to use to parse the input table.
3370
3371        Returns:
3372            The new Create expression.
3373        """
3374        instance = maybe_copy(self, copy)
3375        table_expression = maybe_parse(
3376            table,
3377            into=Table,
3378            dialect=dialect,
3379            **opts,
3380        )
3381        properties_expression = None
3382        if properties:
3383            properties_expression = Properties.from_dict(properties)
3384
3385        return Create(
3386            this=table_expression,
3387            kind="TABLE",
3388            expression=instance,
3389            properties=properties_expression,
3390        )
3391
3392    def lock(self, update: bool = True, copy: bool = True) -> Select:
3393        """
3394        Set the locking read mode for this expression.
3395
3396        Examples:
3397            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3398            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3399
3400            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3401            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3402
3403        Args:
3404            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3405            copy: if `False`, modify this expression instance in-place.
3406
3407        Returns:
3408            The modified expression.
3409        """
3410        inst = maybe_copy(self, copy)
3411        inst.set("locks", [Lock(update=update)])
3412
3413        return inst
3414
3415    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3416        """
3417        Set hints for this expression.
3418
3419        Examples:
3420            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3421            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3422
3423        Args:
3424            hints: The SQL code strings to parse as the hints.
3425                If an `Expression` instance is passed, it will be used as-is.
3426            dialect: The dialect used to parse the hints.
3427            copy: If `False`, modify this expression instance in-place.
3428
3429        Returns:
3430            The modified expression.
3431        """
3432        inst = maybe_copy(self, copy)
3433        inst.set(
3434            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3435        )
3436
3437        return inst
3438
3439    @property
3440    def named_selects(self) -> t.List[str]:
3441        return [e.output_name for e in self.expressions if e.alias_or_name]
3442
3443    @property
3444    def is_star(self) -> bool:
3445        return any(expression.is_star for expression in self.expressions)
3446
3447    @property
3448    def selects(self) -> t.List[Expression]:
3449        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, '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}
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:
2771    def from_(
2772        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2773    ) -> Select:
2774        """
2775        Set the FROM expression.
2776
2777        Example:
2778            >>> Select().from_("tbl").select("x").sql()
2779            'SELECT x FROM tbl'
2780
2781        Args:
2782            expression : the SQL code strings to parse.
2783                If a `From` instance is passed, this is used as-is.
2784                If another `Expression` instance is passed, it will be wrapped in a `From`.
2785            dialect: the dialect used to parse the input expression.
2786            copy: if `False`, modify this expression instance in-place.
2787            opts: other options to use to parse the input expressions.
2788
2789        Returns:
2790            The modified Select expression.
2791        """
2792        return _apply_builder(
2793            expression=expression,
2794            instance=self,
2795            arg="from",
2796            into=From,
2797            prefix="FROM",
2798            dialect=dialect,
2799            copy=copy,
2800            **opts,
2801        )

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:
2803    def group_by(
2804        self,
2805        *expressions: t.Optional[ExpOrStr],
2806        append: bool = True,
2807        dialect: DialectType = None,
2808        copy: bool = True,
2809        **opts,
2810    ) -> Select:
2811        """
2812        Set the GROUP BY expression.
2813
2814        Example:
2815            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2816            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2817
2818        Args:
2819            *expressions: the SQL code strings to parse.
2820                If a `Group` instance is passed, this is used as-is.
2821                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2822                If nothing is passed in then a group by is not applied to the expression
2823            append: if `True`, add to any existing expressions.
2824                Otherwise, this flattens all the `Group` expression into a single expression.
2825            dialect: the dialect used to parse the input expression.
2826            copy: if `False`, modify this expression instance in-place.
2827            opts: other options to use to parse the input expressions.
2828
2829        Returns:
2830            The modified Select expression.
2831        """
2832        if not expressions:
2833            return self if not copy else self.copy()
2834
2835        return _apply_child_list_builder(
2836            *expressions,
2837            instance=self,
2838            arg="group",
2839            append=append,
2840            copy=copy,
2841            prefix="GROUP BY",
2842            into=Group,
2843            dialect=dialect,
2844            **opts,
2845        )

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:
2847    def order_by(
2848        self,
2849        *expressions: t.Optional[ExpOrStr],
2850        append: bool = True,
2851        dialect: DialectType = None,
2852        copy: bool = True,
2853        **opts,
2854    ) -> Select:
2855        """
2856        Set the ORDER BY expression.
2857
2858        Example:
2859            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2860            'SELECT x FROM tbl ORDER BY x DESC'
2861
2862        Args:
2863            *expressions: the SQL code strings to parse.
2864                If a `Group` instance is passed, this is used as-is.
2865                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2866            append: if `True`, add to any existing expressions.
2867                Otherwise, this flattens all the `Order` expression into a single expression.
2868            dialect: the dialect used to parse the input expression.
2869            copy: if `False`, modify this expression instance in-place.
2870            opts: other options to use to parse the input expressions.
2871
2872        Returns:
2873            The modified Select expression.
2874        """
2875        return _apply_child_list_builder(
2876            *expressions,
2877            instance=self,
2878            arg="order",
2879            append=append,
2880            copy=copy,
2881            prefix="ORDER BY",
2882            into=Order,
2883            dialect=dialect,
2884            **opts,
2885        )

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:
2887    def sort_by(
2888        self,
2889        *expressions: t.Optional[ExpOrStr],
2890        append: bool = True,
2891        dialect: DialectType = None,
2892        copy: bool = True,
2893        **opts,
2894    ) -> Select:
2895        """
2896        Set the SORT BY expression.
2897
2898        Example:
2899            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2900            'SELECT x FROM tbl SORT BY x DESC'
2901
2902        Args:
2903            *expressions: the SQL code strings to parse.
2904                If a `Group` instance is passed, this is used as-is.
2905                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2906            append: if `True`, add to any existing expressions.
2907                Otherwise, this flattens all the `Order` expression into a single expression.
2908            dialect: the dialect used to parse the input expression.
2909            copy: if `False`, modify this expression instance in-place.
2910            opts: other options to use to parse the input expressions.
2911
2912        Returns:
2913            The modified Select expression.
2914        """
2915        return _apply_child_list_builder(
2916            *expressions,
2917            instance=self,
2918            arg="sort",
2919            append=append,
2920            copy=copy,
2921            prefix="SORT BY",
2922            into=Sort,
2923            dialect=dialect,
2924            **opts,
2925        )

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:
2927    def cluster_by(
2928        self,
2929        *expressions: t.Optional[ExpOrStr],
2930        append: bool = True,
2931        dialect: DialectType = None,
2932        copy: bool = True,
2933        **opts,
2934    ) -> Select:
2935        """
2936        Set the CLUSTER BY expression.
2937
2938        Example:
2939            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2940            'SELECT x FROM tbl CLUSTER BY x DESC'
2941
2942        Args:
2943            *expressions: the SQL code strings to parse.
2944                If a `Group` instance is passed, this is used as-is.
2945                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2946            append: if `True`, add to any existing expressions.
2947                Otherwise, this flattens all the `Order` expression into a single expression.
2948            dialect: the dialect used to parse the input expression.
2949            copy: if `False`, modify this expression instance in-place.
2950            opts: other options to use to parse the input expressions.
2951
2952        Returns:
2953            The modified Select expression.
2954        """
2955        return _apply_child_list_builder(
2956            *expressions,
2957            instance=self,
2958            arg="cluster",
2959            append=append,
2960            copy=copy,
2961            prefix="CLUSTER BY",
2962            into=Cluster,
2963            dialect=dialect,
2964            **opts,
2965        )

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:
2967    def limit(
2968        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2969    ) -> Select:
2970        """
2971        Set the LIMIT expression.
2972
2973        Example:
2974            >>> Select().from_("tbl").select("x").limit(10).sql()
2975            'SELECT x FROM tbl LIMIT 10'
2976
2977        Args:
2978            expression: the SQL code string to parse.
2979                This can also be an integer.
2980                If a `Limit` instance is passed, this is used as-is.
2981                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
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            Select: the modified expression.
2988        """
2989        return _apply_builder(
2990            expression=expression,
2991            instance=self,
2992            arg="limit",
2993            into=Limit,
2994            prefix="LIMIT",
2995            dialect=dialect,
2996            copy=copy,
2997            into_arg="expression",
2998            **opts,
2999        )

Set the LIMIT expression.

Example:
>>> Select().from_("tbl").select("x").limit(10).sql()
'SELECT x FROM tbl LIMIT 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, this is 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:

Select: the modified 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:
3001    def offset(
3002        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3003    ) -> Select:
3004        """
3005        Set the OFFSET expression.
3006
3007        Example:
3008            >>> Select().from_("tbl").select("x").offset(10).sql()
3009            'SELECT x FROM tbl OFFSET 10'
3010
3011        Args:
3012            expression: the SQL code string to parse.
3013                This can also be an integer.
3014                If a `Offset` instance is passed, this is used as-is.
3015                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3016            dialect: the dialect used to parse the input expression.
3017            copy: if `False`, modify this expression instance in-place.
3018            opts: other options to use to parse the input expressions.
3019
3020        Returns:
3021            The modified Select expression.
3022        """
3023        return _apply_builder(
3024            expression=expression,
3025            instance=self,
3026            arg="offset",
3027            into=Offset,
3028            prefix="OFFSET",
3029            dialect=dialect,
3030            copy=copy,
3031            into_arg="expression",
3032            **opts,
3033        )

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:
3035    def select(
3036        self,
3037        *expressions: t.Optional[ExpOrStr],
3038        append: bool = True,
3039        dialect: DialectType = None,
3040        copy: bool = True,
3041        **opts,
3042    ) -> Select:
3043        """
3044        Append to or set the SELECT expressions.
3045
3046        Example:
3047            >>> Select().select("x", "y").sql()
3048            'SELECT x, y'
3049
3050        Args:
3051            *expressions: the SQL code strings to parse.
3052                If an `Expression` instance is passed, it will be used as-is.
3053            append: if `True`, add to any existing expressions.
3054                Otherwise, this resets the expressions.
3055            dialect: the dialect used to parse the input expressions.
3056            copy: if `False`, modify this expression instance in-place.
3057            opts: other options to use to parse the input expressions.
3058
3059        Returns:
3060            The modified Select expression.
3061        """
3062        return _apply_list_builder(
3063            *expressions,
3064            instance=self,
3065            arg="expressions",
3066            append=append,
3067            dialect=dialect,
3068            copy=copy,
3069            **opts,
3070        )

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 Select 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:
3072    def lateral(
3073        self,
3074        *expressions: t.Optional[ExpOrStr],
3075        append: bool = True,
3076        dialect: DialectType = None,
3077        copy: bool = True,
3078        **opts,
3079    ) -> Select:
3080        """
3081        Append to or set the LATERAL expressions.
3082
3083        Example:
3084            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3085            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3086
3087        Args:
3088            *expressions: the SQL code strings to parse.
3089                If an `Expression` instance is passed, it will be used as-is.
3090            append: if `True`, add to any existing expressions.
3091                Otherwise, this resets the expressions.
3092            dialect: the dialect used to parse the input expressions.
3093            copy: if `False`, modify this expression instance in-place.
3094            opts: other options to use to parse the input expressions.
3095
3096        Returns:
3097            The modified Select expression.
3098        """
3099        return _apply_list_builder(
3100            *expressions,
3101            instance=self,
3102            arg="laterals",
3103            append=append,
3104            into=Lateral,
3105            prefix="LATERAL VIEW",
3106            dialect=dialect,
3107            copy=copy,
3108            **opts,
3109        )

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:
3111    def join(
3112        self,
3113        expression: ExpOrStr,
3114        on: t.Optional[ExpOrStr] = None,
3115        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3116        append: bool = True,
3117        join_type: t.Optional[str] = None,
3118        join_alias: t.Optional[Identifier | str] = None,
3119        dialect: DialectType = None,
3120        copy: bool = True,
3121        **opts,
3122    ) -> Select:
3123        """
3124        Append to or set the JOIN expressions.
3125
3126        Example:
3127            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3128            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3129
3130            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3131            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3132
3133            Use `join_type` to change the type of join:
3134
3135            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3136            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3137
3138        Args:
3139            expression: the SQL code string to parse.
3140                If an `Expression` instance is passed, it will be used as-is.
3141            on: optionally specify the join "on" criteria as a SQL string.
3142                If an `Expression` instance is passed, it will be used as-is.
3143            using: optionally specify the join "using" criteria as a SQL string.
3144                If an `Expression` instance is passed, it will be used as-is.
3145            append: if `True`, add to any existing expressions.
3146                Otherwise, this resets the expressions.
3147            join_type: if set, alter the parsed join type.
3148            join_alias: an optional alias for the joined source.
3149            dialect: the dialect used to parse the input expressions.
3150            copy: if `False`, modify this expression instance in-place.
3151            opts: other options to use to parse the input expressions.
3152
3153        Returns:
3154            Select: the modified expression.
3155        """
3156        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3157
3158        try:
3159            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3160        except ParseError:
3161            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3162
3163        join = expression if isinstance(expression, Join) else Join(this=expression)
3164
3165        if isinstance(join.this, Select):
3166            join.this.replace(join.this.subquery())
3167
3168        if join_type:
3169            method: t.Optional[Token]
3170            side: t.Optional[Token]
3171            kind: t.Optional[Token]
3172
3173            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3174
3175            if method:
3176                join.set("method", method.text)
3177            if side:
3178                join.set("side", side.text)
3179            if kind:
3180                join.set("kind", kind.text)
3181
3182        if on:
3183            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3184            join.set("on", on)
3185
3186        if using:
3187            join = _apply_list_builder(
3188                *ensure_list(using),
3189                instance=join,
3190                arg="using",
3191                append=append,
3192                copy=copy,
3193                into=Identifier,
3194                **opts,
3195            )
3196
3197        if join_alias:
3198            join.set("this", alias_(join.this, join_alias, table=True))
3199
3200        return _apply_list_builder(
3201            join,
3202            instance=self,
3203            arg="joins",
3204            append=append,
3205            copy=copy,
3206            **opts,
3207        )

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:
3209    def where(
3210        self,
3211        *expressions: t.Optional[ExpOrStr],
3212        append: bool = True,
3213        dialect: DialectType = None,
3214        copy: bool = True,
3215        **opts,
3216    ) -> Select:
3217        """
3218        Append to or set the WHERE expressions.
3219
3220        Example:
3221            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3222            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3223
3224        Args:
3225            *expressions: the SQL code strings to parse.
3226                If an `Expression` instance is passed, it will be used as-is.
3227                Multiple expressions are combined with an AND operator.
3228            append: if `True`, AND the new expressions to any existing expression.
3229                Otherwise, this resets the expression.
3230            dialect: the dialect used to parse the input expressions.
3231            copy: if `False`, modify this expression instance in-place.
3232            opts: other options to use to parse the input expressions.
3233
3234        Returns:
3235            Select: the modified expression.
3236        """
3237        return _apply_conjunction_builder(
3238            *expressions,
3239            instance=self,
3240            arg="where",
3241            append=append,
3242            into=Where,
3243            dialect=dialect,
3244            copy=copy,
3245            **opts,
3246        )

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:
3248    def having(
3249        self,
3250        *expressions: t.Optional[ExpOrStr],
3251        append: bool = True,
3252        dialect: DialectType = None,
3253        copy: bool = True,
3254        **opts,
3255    ) -> Select:
3256        """
3257        Append to or set the HAVING expressions.
3258
3259        Example:
3260            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3261            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3262
3263        Args:
3264            *expressions: the SQL code strings to parse.
3265                If an `Expression` instance is passed, it will be used as-is.
3266                Multiple expressions are combined with an AND operator.
3267            append: if `True`, AND the new expressions to any existing expression.
3268                Otherwise, this resets the expression.
3269            dialect: the dialect used to parse the input expressions.
3270            copy: if `False`, modify this expression instance in-place.
3271            opts: other options to use to parse the input expressions.
3272
3273        Returns:
3274            The modified Select expression.
3275        """
3276        return _apply_conjunction_builder(
3277            *expressions,
3278            instance=self,
3279            arg="having",
3280            append=append,
3281            into=Having,
3282            dialect=dialect,
3283            copy=copy,
3284            **opts,
3285        )

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:
3287    def window(
3288        self,
3289        *expressions: t.Optional[ExpOrStr],
3290        append: bool = True,
3291        dialect: DialectType = None,
3292        copy: bool = True,
3293        **opts,
3294    ) -> Select:
3295        return _apply_list_builder(
3296            *expressions,
3297            instance=self,
3298            arg="windows",
3299            append=append,
3300            into=Window,
3301            dialect=dialect,
3302            copy=copy,
3303            **opts,
3304        )
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:
3306    def qualify(
3307        self,
3308        *expressions: t.Optional[ExpOrStr],
3309        append: bool = True,
3310        dialect: DialectType = None,
3311        copy: bool = True,
3312        **opts,
3313    ) -> Select:
3314        return _apply_conjunction_builder(
3315            *expressions,
3316            instance=self,
3317            arg="qualify",
3318            append=append,
3319            into=Qualify,
3320            dialect=dialect,
3321            copy=copy,
3322            **opts,
3323        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3325    def distinct(
3326        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3327    ) -> Select:
3328        """
3329        Set the OFFSET expression.
3330
3331        Example:
3332            >>> Select().from_("tbl").select("x").distinct().sql()
3333            'SELECT DISTINCT x FROM tbl'
3334
3335        Args:
3336            ons: the expressions to distinct on
3337            distinct: whether the Select should be distinct
3338            copy: if `False`, modify this expression instance in-place.
3339
3340        Returns:
3341            Select: the modified expression.
3342        """
3343        instance = maybe_copy(self, copy)
3344        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3345        instance.set("distinct", Distinct(on=on) if distinct else None)
3346        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:
3348    def ctas(
3349        self,
3350        table: ExpOrStr,
3351        properties: t.Optional[t.Dict] = None,
3352        dialect: DialectType = None,
3353        copy: bool = True,
3354        **opts,
3355    ) -> Create:
3356        """
3357        Convert this expression to a CREATE TABLE AS statement.
3358
3359        Example:
3360            >>> Select().select("*").from_("tbl").ctas("x").sql()
3361            'CREATE TABLE x AS SELECT * FROM tbl'
3362
3363        Args:
3364            table: the SQL code string to parse as the table name.
3365                If another `Expression` instance is passed, it will be used as-is.
3366            properties: an optional mapping of table properties
3367            dialect: the dialect used to parse the input table.
3368            copy: if `False`, modify this expression instance in-place.
3369            opts: other options to use to parse the input table.
3370
3371        Returns:
3372            The new Create expression.
3373        """
3374        instance = maybe_copy(self, copy)
3375        table_expression = maybe_parse(
3376            table,
3377            into=Table,
3378            dialect=dialect,
3379            **opts,
3380        )
3381        properties_expression = None
3382        if properties:
3383            properties_expression = Properties.from_dict(properties)
3384
3385        return Create(
3386            this=table_expression,
3387            kind="TABLE",
3388            expression=instance,
3389            properties=properties_expression,
3390        )

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:
3392    def lock(self, update: bool = True, copy: bool = True) -> Select:
3393        """
3394        Set the locking read mode for this expression.
3395
3396        Examples:
3397            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3398            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3399
3400            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3401            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3402
3403        Args:
3404            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3405            copy: if `False`, modify this expression instance in-place.
3406
3407        Returns:
3408            The modified expression.
3409        """
3410        inst = maybe_copy(self, copy)
3411        inst.set("locks", [Lock(update=update)])
3412
3413        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:
3415    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3416        """
3417        Set hints for this expression.
3418
3419        Examples:
3420            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3421            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3422
3423        Args:
3424            hints: The SQL code strings to parse as the hints.
3425                If an `Expression` instance is passed, it will be used as-is.
3426            dialect: The dialect used to parse the hints.
3427            copy: If `False`, modify this expression instance in-place.
3428
3429        Returns:
3430            The modified expression.
3431        """
3432        inst = maybe_copy(self, copy)
3433        inst.set(
3434            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3435        )
3436
3437        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]
3439    @property
3440    def named_selects(self) -> t.List[str]:
3441        return [e.output_name for e in self.expressions if e.alias_or_name]
is_star: bool
3443    @property
3444    def is_star(self) -> bool:
3445        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3447    @property
3448    def selects(self) -> t.List[Expression]:
3449        return self.expressions
key = 'select'
class Subquery(DerivedTable, Unionable):
3452class Subquery(DerivedTable, Unionable):
3453    arg_types = {
3454        "this": True,
3455        "alias": False,
3456        "with": False,
3457        **QUERY_MODIFIERS,
3458    }
3459
3460    def unnest(self):
3461        """
3462        Returns the first non subquery.
3463        """
3464        expression = self
3465        while isinstance(expression, Subquery):
3466            expression = expression.this
3467        return expression
3468
3469    def unwrap(self) -> Subquery:
3470        expression = self
3471        while expression.same_parent and expression.is_wrapper:
3472            expression = t.cast(Subquery, expression.parent)
3473        return expression
3474
3475    @property
3476    def is_wrapper(self) -> bool:
3477        """
3478        Whether this Subquery acts as a simple wrapper around another expression.
3479
3480        SELECT * FROM (((SELECT * FROM t)))
3481                      ^
3482                      This corresponds to a "wrapper" Subquery node
3483        """
3484        return all(v is None for k, v in self.args.items() if k != "this")
3485
3486    @property
3487    def is_star(self) -> bool:
3488        return self.this.is_star
3489
3490    @property
3491    def output_name(self) -> str:
3492        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
def unnest(self):
3460    def unnest(self):
3461        """
3462        Returns the first non subquery.
3463        """
3464        expression = self
3465        while isinstance(expression, Subquery):
3466            expression = expression.this
3467        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3469    def unwrap(self) -> Subquery:
3470        expression = self
3471        while expression.same_parent and expression.is_wrapper:
3472            expression = t.cast(Subquery, expression.parent)
3473        return expression
is_wrapper: bool
3475    @property
3476    def is_wrapper(self) -> bool:
3477        """
3478        Whether this Subquery acts as a simple wrapper around another expression.
3479
3480        SELECT * FROM (((SELECT * FROM t)))
3481                      ^
3482                      This corresponds to a "wrapper" Subquery node
3483        """
3484        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
3486    @property
3487    def is_star(self) -> bool:
3488        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3490    @property
3491    def output_name(self) -> str:
3492        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):
3495class TableSample(Expression):
3496    arg_types = {
3497        "this": False,
3498        "expressions": False,
3499        "method": False,
3500        "bucket_numerator": False,
3501        "bucket_denominator": False,
3502        "bucket_field": False,
3503        "percent": False,
3504        "rows": False,
3505        "size": False,
3506        "seed": False,
3507    }
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):
3510class Tag(Expression):
3511    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3512
3513    arg_types = {
3514        "this": False,
3515        "prefix": False,
3516        "postfix": False,
3517    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3522class Pivot(Expression):
3523    arg_types = {
3524        "this": False,
3525        "alias": False,
3526        "expressions": False,
3527        "field": False,
3528        "unpivot": False,
3529        "using": False,
3530        "group": False,
3531        "columns": False,
3532        "include_nulls": False,
3533    }
3534
3535    @property
3536    def unpivot(self) -> bool:
3537        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
3535    @property
3536    def unpivot(self) -> bool:
3537        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3540class Window(Condition):
3541    arg_types = {
3542        "this": True,
3543        "partition_by": False,
3544        "order": False,
3545        "spec": False,
3546        "alias": False,
3547        "over": False,
3548        "first": False,
3549    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3552class WindowSpec(Expression):
3553    arg_types = {
3554        "kind": False,
3555        "start": False,
3556        "start_side": False,
3557        "end": False,
3558        "end_side": False,
3559    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3562class Where(Expression):
3563    pass
key = 'where'
class Star(Expression):
3566class Star(Expression):
3567    arg_types = {"except": False, "replace": False}
3568
3569    @property
3570    def name(self) -> str:
3571        return "*"
3572
3573    @property
3574    def output_name(self) -> str:
3575        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3569    @property
3570    def name(self) -> str:
3571        return "*"
output_name: str
3573    @property
3574    def output_name(self) -> str:
3575        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):
3578class Parameter(Condition):
3579    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3582class SessionParameter(Condition):
3583    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3586class Placeholder(Condition):
3587    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3590class Null(Condition):
3591    arg_types: t.Dict[str, t.Any] = {}
3592
3593    @property
3594    def name(self) -> str:
3595        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3593    @property
3594    def name(self) -> str:
3595        return "NULL"
key = 'null'
class Boolean(Condition):
3598class Boolean(Condition):
3599    pass
key = 'boolean'
class DataTypeParam(Expression):
3602class DataTypeParam(Expression):
3603    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3606class DataType(Expression):
3607    arg_types = {
3608        "this": True,
3609        "expressions": False,
3610        "nested": False,
3611        "values": False,
3612        "prefix": False,
3613        "kind": False,
3614    }
3615
3616    class Type(AutoName):
3617        ARRAY = auto()
3618        BIGDECIMAL = auto()
3619        BIGINT = auto()
3620        BIGSERIAL = auto()
3621        BINARY = auto()
3622        BIT = auto()
3623        BOOLEAN = auto()
3624        CHAR = auto()
3625        DATE = auto()
3626        DATEMULTIRANGE = auto()
3627        DATERANGE = auto()
3628        DATETIME = auto()
3629        DATETIME64 = auto()
3630        DECIMAL = auto()
3631        DOUBLE = auto()
3632        ENUM = auto()
3633        ENUM8 = auto()
3634        ENUM16 = auto()
3635        FIXEDSTRING = auto()
3636        FLOAT = auto()
3637        GEOGRAPHY = auto()
3638        GEOMETRY = auto()
3639        HLLSKETCH = auto()
3640        HSTORE = auto()
3641        IMAGE = auto()
3642        INET = auto()
3643        INT = auto()
3644        INT128 = auto()
3645        INT256 = auto()
3646        INT4MULTIRANGE = auto()
3647        INT4RANGE = auto()
3648        INT8MULTIRANGE = auto()
3649        INT8RANGE = auto()
3650        INTERVAL = auto()
3651        IPADDRESS = auto()
3652        IPPREFIX = auto()
3653        JSON = auto()
3654        JSONB = auto()
3655        LONGBLOB = auto()
3656        LONGTEXT = auto()
3657        LOWCARDINALITY = auto()
3658        MAP = auto()
3659        MEDIUMBLOB = auto()
3660        MEDIUMINT = auto()
3661        MEDIUMTEXT = auto()
3662        MONEY = auto()
3663        NCHAR = auto()
3664        NESTED = auto()
3665        NULL = auto()
3666        NULLABLE = auto()
3667        NUMMULTIRANGE = auto()
3668        NUMRANGE = auto()
3669        NVARCHAR = auto()
3670        OBJECT = auto()
3671        ROWVERSION = auto()
3672        SERIAL = auto()
3673        SET = auto()
3674        SMALLINT = auto()
3675        SMALLMONEY = auto()
3676        SMALLSERIAL = auto()
3677        STRUCT = auto()
3678        SUPER = auto()
3679        TEXT = auto()
3680        TINYBLOB = auto()
3681        TINYTEXT = auto()
3682        TIME = auto()
3683        TIMETZ = auto()
3684        TIMESTAMP = auto()
3685        TIMESTAMPLTZ = auto()
3686        TIMESTAMPTZ = auto()
3687        TIMESTAMP_S = auto()
3688        TIMESTAMP_MS = auto()
3689        TIMESTAMP_NS = auto()
3690        TINYINT = auto()
3691        TSMULTIRANGE = auto()
3692        TSRANGE = auto()
3693        TSTZMULTIRANGE = auto()
3694        TSTZRANGE = auto()
3695        UBIGINT = auto()
3696        UINT = auto()
3697        UINT128 = auto()
3698        UINT256 = auto()
3699        UMEDIUMINT = auto()
3700        UDECIMAL = auto()
3701        UNIQUEIDENTIFIER = auto()
3702        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3703        USERDEFINED = "USER-DEFINED"
3704        USMALLINT = auto()
3705        UTINYINT = auto()
3706        UUID = auto()
3707        VARBINARY = auto()
3708        VARCHAR = auto()
3709        VARIANT = auto()
3710        XML = auto()
3711        YEAR = auto()
3712
3713    TEXT_TYPES = {
3714        Type.CHAR,
3715        Type.NCHAR,
3716        Type.VARCHAR,
3717        Type.NVARCHAR,
3718        Type.TEXT,
3719    }
3720
3721    INTEGER_TYPES = {
3722        Type.INT,
3723        Type.TINYINT,
3724        Type.SMALLINT,
3725        Type.BIGINT,
3726        Type.INT128,
3727        Type.INT256,
3728        Type.BIT,
3729    }
3730
3731    FLOAT_TYPES = {
3732        Type.FLOAT,
3733        Type.DOUBLE,
3734    }
3735
3736    NUMERIC_TYPES = {
3737        *INTEGER_TYPES,
3738        *FLOAT_TYPES,
3739    }
3740
3741    TEMPORAL_TYPES = {
3742        Type.TIME,
3743        Type.TIMETZ,
3744        Type.TIMESTAMP,
3745        Type.TIMESTAMPTZ,
3746        Type.TIMESTAMPLTZ,
3747        Type.TIMESTAMP_S,
3748        Type.TIMESTAMP_MS,
3749        Type.TIMESTAMP_NS,
3750        Type.DATE,
3751        Type.DATETIME,
3752        Type.DATETIME64,
3753    }
3754
3755    @classmethod
3756    def build(
3757        cls,
3758        dtype: DATA_TYPE,
3759        dialect: DialectType = None,
3760        udt: bool = False,
3761        **kwargs,
3762    ) -> DataType:
3763        """
3764        Constructs a DataType object.
3765
3766        Args:
3767            dtype: the data type of interest.
3768            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3769            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3770                DataType, thus creating a user-defined type.
3771            kawrgs: additional arguments to pass in the constructor of DataType.
3772
3773        Returns:
3774            The constructed DataType object.
3775        """
3776        from sqlglot import parse_one
3777
3778        if isinstance(dtype, str):
3779            if dtype.upper() == "UNKNOWN":
3780                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3781
3782            try:
3783                data_type_exp = parse_one(
3784                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3785                )
3786            except ParseError:
3787                if udt:
3788                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3789                raise
3790        elif isinstance(dtype, DataType.Type):
3791            data_type_exp = DataType(this=dtype)
3792        elif isinstance(dtype, DataType):
3793            return dtype
3794        else:
3795            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3796
3797        return DataType(**{**data_type_exp.args, **kwargs})
3798
3799    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3800        """
3801        Checks whether this DataType matches one of the provided data types. Nested types or precision
3802        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3803
3804        Args:
3805            dtypes: the data types to compare this DataType to.
3806
3807        Returns:
3808            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3809        """
3810        for dtype in dtypes:
3811            other = DataType.build(dtype, udt=True)
3812
3813            if (
3814                other.expressions
3815                or self.this == DataType.Type.USERDEFINED
3816                or other.this == DataType.Type.USERDEFINED
3817            ):
3818                matches = self == other
3819            else:
3820                matches = self.this == other.this
3821
3822            if matches:
3823                return True
3824        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>}
INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.INT: 'INT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.FLOAT: 'FLOAT'>, <Type.BIT: 'BIT'>, <Type.BIGINT: 'BIGINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <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, **kwargs) -> DataType:
3755    @classmethod
3756    def build(
3757        cls,
3758        dtype: DATA_TYPE,
3759        dialect: DialectType = None,
3760        udt: bool = False,
3761        **kwargs,
3762    ) -> DataType:
3763        """
3764        Constructs a DataType object.
3765
3766        Args:
3767            dtype: the data type of interest.
3768            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3769            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3770                DataType, thus creating a user-defined type.
3771            kawrgs: additional arguments to pass in the constructor of DataType.
3772
3773        Returns:
3774            The constructed DataType object.
3775        """
3776        from sqlglot import parse_one
3777
3778        if isinstance(dtype, str):
3779            if dtype.upper() == "UNKNOWN":
3780                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3781
3782            try:
3783                data_type_exp = parse_one(
3784                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3785                )
3786            except ParseError:
3787                if udt:
3788                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3789                raise
3790        elif isinstance(dtype, DataType.Type):
3791            data_type_exp = DataType(this=dtype)
3792        elif isinstance(dtype, DataType):
3793            return dtype
3794        else:
3795            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3796
3797        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.
  • kawrgs: 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:
3799    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3800        """
3801        Checks whether this DataType matches one of the provided data types. Nested types or precision
3802        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3803
3804        Args:
3805            dtypes: the data types to compare this DataType to.
3806
3807        Returns:
3808            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3809        """
3810        for dtype in dtypes:
3811            other = DataType.build(dtype, udt=True)
3812
3813            if (
3814                other.expressions
3815                or self.this == DataType.Type.USERDEFINED
3816                or other.this == DataType.Type.USERDEFINED
3817            ):
3818                matches = self == other
3819            else:
3820                matches = self.this == other.this
3821
3822            if matches:
3823                return True
3824        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):
3616    class Type(AutoName):
3617        ARRAY = auto()
3618        BIGDECIMAL = auto()
3619        BIGINT = auto()
3620        BIGSERIAL = auto()
3621        BINARY = auto()
3622        BIT = auto()
3623        BOOLEAN = auto()
3624        CHAR = auto()
3625        DATE = auto()
3626        DATEMULTIRANGE = auto()
3627        DATERANGE = auto()
3628        DATETIME = auto()
3629        DATETIME64 = auto()
3630        DECIMAL = auto()
3631        DOUBLE = auto()
3632        ENUM = auto()
3633        ENUM8 = auto()
3634        ENUM16 = auto()
3635        FIXEDSTRING = auto()
3636        FLOAT = auto()
3637        GEOGRAPHY = auto()
3638        GEOMETRY = auto()
3639        HLLSKETCH = auto()
3640        HSTORE = auto()
3641        IMAGE = auto()
3642        INET = auto()
3643        INT = auto()
3644        INT128 = auto()
3645        INT256 = auto()
3646        INT4MULTIRANGE = auto()
3647        INT4RANGE = auto()
3648        INT8MULTIRANGE = auto()
3649        INT8RANGE = auto()
3650        INTERVAL = auto()
3651        IPADDRESS = auto()
3652        IPPREFIX = auto()
3653        JSON = auto()
3654        JSONB = auto()
3655        LONGBLOB = auto()
3656        LONGTEXT = auto()
3657        LOWCARDINALITY = auto()
3658        MAP = auto()
3659        MEDIUMBLOB = auto()
3660        MEDIUMINT = auto()
3661        MEDIUMTEXT = auto()
3662        MONEY = auto()
3663        NCHAR = auto()
3664        NESTED = auto()
3665        NULL = auto()
3666        NULLABLE = auto()
3667        NUMMULTIRANGE = auto()
3668        NUMRANGE = auto()
3669        NVARCHAR = auto()
3670        OBJECT = auto()
3671        ROWVERSION = auto()
3672        SERIAL = auto()
3673        SET = auto()
3674        SMALLINT = auto()
3675        SMALLMONEY = auto()
3676        SMALLSERIAL = auto()
3677        STRUCT = auto()
3678        SUPER = auto()
3679        TEXT = auto()
3680        TINYBLOB = auto()
3681        TINYTEXT = auto()
3682        TIME = auto()
3683        TIMETZ = auto()
3684        TIMESTAMP = auto()
3685        TIMESTAMPLTZ = auto()
3686        TIMESTAMPTZ = auto()
3687        TIMESTAMP_S = auto()
3688        TIMESTAMP_MS = auto()
3689        TIMESTAMP_NS = auto()
3690        TINYINT = auto()
3691        TSMULTIRANGE = auto()
3692        TSRANGE = auto()
3693        TSTZMULTIRANGE = auto()
3694        TSTZRANGE = auto()
3695        UBIGINT = auto()
3696        UINT = auto()
3697        UINT128 = auto()
3698        UINT256 = auto()
3699        UMEDIUMINT = auto()
3700        UDECIMAL = auto()
3701        UNIQUEIDENTIFIER = auto()
3702        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3703        USERDEFINED = "USER-DEFINED"
3704        USMALLINT = auto()
3705        UTINYINT = auto()
3706        UUID = auto()
3707        VARBINARY = auto()
3708        VARCHAR = auto()
3709        VARIANT = auto()
3710        XML = auto()
3711        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
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'>
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'>
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):
3831class PseudoType(DataType):
3832    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3836class ObjectIdentifier(DataType):
3837    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3841class SubqueryPredicate(Predicate):
3842    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3845class All(SubqueryPredicate):
3846    pass
key = 'all'
class Any(SubqueryPredicate):
3849class Any(SubqueryPredicate):
3850    pass
key = 'any'
class Exists(SubqueryPredicate):
3853class Exists(SubqueryPredicate):
3854    pass
key = 'exists'
class Command(Expression):
3859class Command(Expression):
3860    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3863class Transaction(Expression):
3864    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3867class Commit(Expression):
3868    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3871class Rollback(Expression):
3872    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3875class AlterTable(Expression):
3876    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False}
key = 'altertable'
class AddConstraint(Expression):
3879class AddConstraint(Expression):
3880    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3883class DropPartition(Expression):
3884    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3888class Binary(Condition):
3889    arg_types = {"this": True, "expression": True}
3890
3891    @property
3892    def left(self) -> Expression:
3893        return self.this
3894
3895    @property
3896    def right(self) -> Expression:
3897        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3891    @property
3892    def left(self) -> Expression:
3893        return self.this
right: Expression
3895    @property
3896    def right(self) -> Expression:
3897        return self.expression
key = 'binary'
class Add(Binary):
3900class Add(Binary):
3901    pass
key = 'add'
class Connector(Binary):
3904class Connector(Binary):
3905    pass
key = 'connector'
class And(Connector):
3908class And(Connector):
3909    pass
key = 'and'
class Or(Connector):
3912class Or(Connector):
3913    pass
key = 'or'
class BitwiseAnd(Binary):
3916class BitwiseAnd(Binary):
3917    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3920class BitwiseLeftShift(Binary):
3921    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3924class BitwiseOr(Binary):
3925    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3928class BitwiseRightShift(Binary):
3929    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3932class BitwiseXor(Binary):
3933    pass
key = 'bitwisexor'
class Div(Binary):
3936class Div(Binary):
3937    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):
3940class Overlaps(Binary):
3941    pass
key = 'overlaps'
class Dot(Binary):
3944class Dot(Binary):
3945    @property
3946    def name(self) -> str:
3947        return self.expression.name
3948
3949    @property
3950    def output_name(self) -> str:
3951        return self.name
3952
3953    @classmethod
3954    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3955        """Build a Dot object with a sequence of expressions."""
3956        if len(expressions) < 2:
3957            raise ValueError(f"Dot requires >= 2 expressions.")
3958
3959        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
3960
3961    @property
3962    def parts(self) -> t.List[Expression]:
3963        """Return the parts of a table / column in order catalog, db, table."""
3964        this, *parts = self.flatten()
3965
3966        parts.reverse()
3967
3968        for arg in ("this", "table", "db", "catalog"):
3969            part = this.args.get(arg)
3970
3971            if isinstance(part, Expression):
3972                parts.append(part)
3973
3974        parts.reverse()
3975        return parts
name: str
3945    @property
3946    def name(self) -> str:
3947        return self.expression.name
output_name: str
3949    @property
3950    def output_name(self) -> str:
3951        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:
3953    @classmethod
3954    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3955        """Build a Dot object with a sequence of expressions."""
3956        if len(expressions) < 2:
3957            raise ValueError(f"Dot requires >= 2 expressions.")
3958
3959        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]
3961    @property
3962    def parts(self) -> t.List[Expression]:
3963        """Return the parts of a table / column in order catalog, db, table."""
3964        this, *parts = self.flatten()
3965
3966        parts.reverse()
3967
3968        for arg in ("this", "table", "db", "catalog"):
3969            part = this.args.get(arg)
3970
3971            if isinstance(part, Expression):
3972                parts.append(part)
3973
3974        parts.reverse()
3975        return parts

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

key = 'dot'
class DPipe(Binary):
3978class DPipe(Binary):
3979    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
3982class EQ(Binary, Predicate):
3983    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3986class NullSafeEQ(Binary, Predicate):
3987    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3990class NullSafeNEQ(Binary, Predicate):
3991    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3995class PropertyEQ(Binary):
3996    pass
key = 'propertyeq'
class Distance(Binary):
3999class Distance(Binary):
4000    pass
key = 'distance'
class Escape(Binary):
4003class Escape(Binary):
4004    pass
key = 'escape'
class Glob(Binary, Predicate):
4007class Glob(Binary, Predicate):
4008    pass
key = 'glob'
class GT(Binary, Predicate):
4011class GT(Binary, Predicate):
4012    pass
key = 'gt'
class GTE(Binary, Predicate):
4015class GTE(Binary, Predicate):
4016    pass
key = 'gte'
class ILike(Binary, Predicate):
4019class ILike(Binary, Predicate):
4020    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4023class ILikeAny(Binary, Predicate):
4024    pass
key = 'ilikeany'
class IntDiv(Binary):
4027class IntDiv(Binary):
4028    pass
key = 'intdiv'
class Is(Binary, Predicate):
4031class Is(Binary, Predicate):
4032    pass
key = 'is'
class Kwarg(Binary):
4035class Kwarg(Binary):
4036    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4039class Like(Binary, Predicate):
4040    pass
key = 'like'
class LikeAny(Binary, Predicate):
4043class LikeAny(Binary, Predicate):
4044    pass
key = 'likeany'
class LT(Binary, Predicate):
4047class LT(Binary, Predicate):
4048    pass
key = 'lt'
class LTE(Binary, Predicate):
4051class LTE(Binary, Predicate):
4052    pass
key = 'lte'
class Mod(Binary):
4055class Mod(Binary):
4056    pass
key = 'mod'
class Mul(Binary):
4059class Mul(Binary):
4060    pass
key = 'mul'
class NEQ(Binary, Predicate):
4063class NEQ(Binary, Predicate):
4064    pass
key = 'neq'
class Operator(Binary):
4068class Operator(Binary):
4069    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4072class SimilarTo(Binary, Predicate):
4073    pass
key = 'similarto'
class Slice(Binary):
4076class Slice(Binary):
4077    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4080class Sub(Binary):
4081    pass
key = 'sub'
class ArrayOverlaps(Binary):
4084class ArrayOverlaps(Binary):
4085    pass
key = 'arrayoverlaps'
class Unary(Condition):
4090class Unary(Condition):
4091    pass
key = 'unary'
class BitwiseNot(Unary):
4094class BitwiseNot(Unary):
4095    pass
key = 'bitwisenot'
class Not(Unary):
4098class Not(Unary):
4099    pass
key = 'not'
class Paren(Unary):
4102class Paren(Unary):
4103    arg_types = {"this": True, "with": False}
4104
4105    @property
4106    def output_name(self) -> str:
4107        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4105    @property
4106    def output_name(self) -> str:
4107        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):
4110class Neg(Unary):
4111    pass
key = 'neg'
class Alias(Expression):
4114class Alias(Expression):
4115    arg_types = {"this": True, "alias": False}
4116
4117    @property
4118    def output_name(self) -> str:
4119        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4117    @property
4118    def output_name(self) -> str:
4119        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):
4124class PivotAlias(Alias):
4125    pass
key = 'pivotalias'
class Aliases(Expression):
4128class Aliases(Expression):
4129    arg_types = {"this": True, "expressions": True}
4130
4131    @property
4132    def aliases(self):
4133        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4131    @property
4132    def aliases(self):
4133        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4137class AtIndex(Expression):
4138    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4141class AtTimeZone(Expression):
4142    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4145class Between(Predicate):
4146    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4149class Bracket(Condition):
4150    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4151    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4152
4153    @property
4154    def output_name(self) -> str:
4155        if len(self.expressions) == 1:
4156            return self.expressions[0].output_name
4157
4158        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4153    @property
4154    def output_name(self) -> str:
4155        if len(self.expressions) == 1:
4156            return self.expressions[0].output_name
4157
4158        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):
4161class Distinct(Expression):
4162    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4165class In(Predicate):
4166    arg_types = {
4167        "this": True,
4168        "expressions": False,
4169        "query": False,
4170        "unnest": False,
4171        "field": False,
4172        "is_global": False,
4173    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4177class ForIn(Expression):
4178    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4181class TimeUnit(Expression):
4182    """Automatically converts unit arg into a var."""
4183
4184    arg_types = {"unit": False}
4185
4186    UNABBREVIATED_UNIT_NAME = {
4187        "D": "DAY",
4188        "H": "HOUR",
4189        "M": "MINUTE",
4190        "MS": "MILLISECOND",
4191        "NS": "NANOSECOND",
4192        "Q": "QUARTER",
4193        "S": "SECOND",
4194        "US": "MICROSECOND",
4195        "W": "WEEK",
4196        "Y": "YEAR",
4197    }
4198
4199    VAR_LIKE = (Column, Literal, Var)
4200
4201    def __init__(self, **args):
4202        unit = args.get("unit")
4203        if isinstance(unit, self.VAR_LIKE):
4204            args["unit"] = Var(
4205                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4206            )
4207        elif isinstance(unit, Week):
4208            unit.set("this", Var(this=unit.this.name.upper()))
4209
4210        super().__init__(**args)
4211
4212    @property
4213    def unit(self) -> t.Optional[Var]:
4214        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4201    def __init__(self, **args):
4202        unit = args.get("unit")
4203        if isinstance(unit, self.VAR_LIKE):
4204            args["unit"] = Var(
4205                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4206            )
4207        elif isinstance(unit, Week):
4208            unit.set("this", Var(this=unit.this.name.upper()))
4209
4210        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]
4212    @property
4213    def unit(self) -> t.Optional[Var]:
4214        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4217class IntervalOp(TimeUnit):
4218    arg_types = {"unit": True, "expression": True}
4219
4220    def interval(self):
4221        return Interval(
4222            this=self.expression.copy(),
4223            unit=self.unit.copy(),
4224        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4220    def interval(self):
4221        return Interval(
4222            this=self.expression.copy(),
4223            unit=self.unit.copy(),
4224        )
key = 'intervalop'
class IntervalSpan(DataType):
4230class IntervalSpan(DataType):
4231    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4234class Interval(TimeUnit):
4235    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4238class IgnoreNulls(Expression):
4239    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4242class RespectNulls(Expression):
4243    pass
key = 'respectnulls'
class Func(Condition):
4247class Func(Condition):
4248    """
4249    The base class for all function expressions.
4250
4251    Attributes:
4252        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4253            treated as a variable length argument and the argument's value will be stored as a list.
4254        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4255            for this function expression. These values are used to map this node to a name during parsing
4256            as well as to provide the function's name during SQL string generation. By default the SQL
4257            name is set to the expression's class name transformed to snake case.
4258    """
4259
4260    is_var_len_args = False
4261
4262    @classmethod
4263    def from_arg_list(cls, args):
4264        if cls.is_var_len_args:
4265            all_arg_keys = list(cls.arg_types)
4266            # If this function supports variable length argument treat the last argument as such.
4267            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4268            num_non_var = len(non_var_len_arg_keys)
4269
4270            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4271            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4272        else:
4273            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4274
4275        return cls(**args_dict)
4276
4277    @classmethod
4278    def sql_names(cls):
4279        if cls is Func:
4280            raise NotImplementedError(
4281                "SQL name is only supported by concrete function implementations"
4282            )
4283        if "_sql_names" not in cls.__dict__:
4284            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4285        return cls._sql_names
4286
4287    @classmethod
4288    def sql_name(cls):
4289        return cls.sql_names()[0]
4290
4291    @classmethod
4292    def default_parser_mappings(cls):
4293        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): determines 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):
4262    @classmethod
4263    def from_arg_list(cls, args):
4264        if cls.is_var_len_args:
4265            all_arg_keys = list(cls.arg_types)
4266            # If this function supports variable length argument treat the last argument as such.
4267            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4268            num_non_var = len(non_var_len_arg_keys)
4269
4270            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4271            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4272        else:
4273            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4274
4275        return cls(**args_dict)
@classmethod
def sql_names(cls):
4277    @classmethod
4278    def sql_names(cls):
4279        if cls is Func:
4280            raise NotImplementedError(
4281                "SQL name is only supported by concrete function implementations"
4282            )
4283        if "_sql_names" not in cls.__dict__:
4284            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4285        return cls._sql_names
@classmethod
def sql_name(cls):
4287    @classmethod
4288    def sql_name(cls):
4289        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4291    @classmethod
4292    def default_parser_mappings(cls):
4293        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4296class AggFunc(Func):
4297    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4300class ParameterizedAgg(AggFunc):
4301    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4304class Abs(Func):
4305    pass
key = 'abs'
class ArgMax(AggFunc):
4308class ArgMax(AggFunc):
4309    arg_types = {"this": True, "expression": True, "count": False}
4310    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4313class ArgMin(AggFunc):
4314    arg_types = {"this": True, "expression": True, "count": False}
4315    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4318class ApproxTopK(AggFunc):
4319    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4322class Flatten(Func):
4323    pass
key = 'flatten'
class Transform(Func):
4327class Transform(Func):
4328    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4331class Anonymous(Func):
4332    arg_types = {"this": True, "expressions": False}
4333    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4336class AnonymousAggFunc(AggFunc):
4337    arg_types = {"this": True, "expressions": False}
4338    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4342class CombinedAggFunc(AnonymousAggFunc):
4343    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4346class CombinedParameterizedAgg(ParameterizedAgg):
4347    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):
4352class Hll(AggFunc):
4353    arg_types = {"this": True, "expressions": False}
4354    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4357class ApproxDistinct(AggFunc):
4358    arg_types = {"this": True, "accuracy": False}
4359    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4362class Array(Func):
4363    arg_types = {"expressions": False}
4364    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4368class ToArray(Func):
4369    pass
key = 'toarray'
class ToChar(Func):
4374class ToChar(Func):
4375    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4378class GenerateSeries(Func):
4379    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4382class ArrayAgg(AggFunc):
4383    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4386class ArrayUniqueAgg(AggFunc):
4387    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4390class ArrayAll(Func):
4391    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4394class ArrayAny(Func):
4395    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4398class ArrayConcat(Func):
4399    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4400    arg_types = {"this": True, "expressions": False}
4401    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4404class ArrayContains(Binary, Func):
4405    pass
key = 'arraycontains'
class ArrayContained(Binary):
4408class ArrayContained(Binary):
4409    pass
key = 'arraycontained'
class ArrayFilter(Func):
4412class ArrayFilter(Func):
4413    arg_types = {"this": True, "expression": True}
4414    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4417class ArrayJoin(Func):
4418    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4421class ArraySize(Func):
4422    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4425class ArraySort(Func):
4426    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4429class ArraySum(Func):
4430    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4433class ArrayUnionAgg(AggFunc):
4434    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4437class Avg(AggFunc):
4438    pass
key = 'avg'
class AnyValue(AggFunc):
4441class AnyValue(AggFunc):
4442    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
arg_types = {'this': True, 'having': False, 'max': False, 'ignore_nulls': False}
key = 'anyvalue'
class First(Func):
4445class First(Func):
4446    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4449class Last(Func):
4450    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4453class Case(Func):
4454    arg_types = {"this": False, "ifs": True, "default": False}
4455
4456    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4457        instance = maybe_copy(self, copy)
4458        instance.append(
4459            "ifs",
4460            If(
4461                this=maybe_parse(condition, copy=copy, **opts),
4462                true=maybe_parse(then, copy=copy, **opts),
4463            ),
4464        )
4465        return instance
4466
4467    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4468        instance = maybe_copy(self, copy)
4469        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4470        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:
4456    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4457        instance = maybe_copy(self, copy)
4458        instance.append(
4459            "ifs",
4460            If(
4461                this=maybe_parse(condition, copy=copy, **opts),
4462                true=maybe_parse(then, copy=copy, **opts),
4463            ),
4464        )
4465        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4467    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4468        instance = maybe_copy(self, copy)
4469        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4470        return instance
key = 'case'
class Cast(Func):
4473class Cast(Func):
4474    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4475
4476    @property
4477    def name(self) -> str:
4478        return self.this.name
4479
4480    @property
4481    def to(self) -> DataType:
4482        return self.args["to"]
4483
4484    @property
4485    def output_name(self) -> str:
4486        return self.name
4487
4488    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4489        """
4490        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4491        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4492        array<int> != array<float>.
4493
4494        Args:
4495            dtypes: the data types to compare this Cast's DataType to.
4496
4497        Returns:
4498            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4499        """
4500        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4476    @property
4477    def name(self) -> str:
4478        return self.this.name
to: DataType
4480    @property
4481    def to(self) -> DataType:
4482        return self.args["to"]
output_name: str
4484    @property
4485    def output_name(self) -> str:
4486        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:
4488    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4489        """
4490        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4491        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4492        array<int> != array<float>.
4493
4494        Args:
4495            dtypes: the data types to compare this Cast's DataType to.
4496
4497        Returns:
4498            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4499        """
4500        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):
4503class TryCast(Cast):
4504    pass
key = 'trycast'
class CastToStrType(Func):
4507class CastToStrType(Func):
4508    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4511class Collate(Binary, Func):
4512    pass
key = 'collate'
class Ceil(Func):
4515class Ceil(Func):
4516    arg_types = {"this": True, "decimals": False}
4517    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4520class Coalesce(Func):
4521    arg_types = {"this": True, "expressions": False}
4522    is_var_len_args = True
4523    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4526class Chr(Func):
4527    arg_types = {"this": True, "charset": False, "expressions": False}
4528    is_var_len_args = True
4529    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4532class Concat(Func):
4533    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4534    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4537class ConcatWs(Concat):
4538    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4541class Count(AggFunc):
4542    arg_types = {"this": False, "expressions": False}
4543    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4546class CountIf(AggFunc):
4547    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4550class CurrentDate(Func):
4551    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4554class CurrentDatetime(Func):
4555    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4558class CurrentTime(Func):
4559    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4562class CurrentTimestamp(Func):
4563    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4566class CurrentUser(Func):
4567    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4570class DateAdd(Func, IntervalOp):
4571    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4574class DateSub(Func, IntervalOp):
4575    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4578class DateDiff(Func, TimeUnit):
4579    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4580    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4583class DateTrunc(Func):
4584    arg_types = {"unit": True, "this": True, "zone": False}
4585
4586    def __init__(self, **args):
4587        unit = args.get("unit")
4588        if isinstance(unit, TimeUnit.VAR_LIKE):
4589            args["unit"] = Literal.string(
4590                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4591            )
4592        elif isinstance(unit, Week):
4593            unit.set("this", Literal.string(unit.this.name.upper()))
4594
4595        super().__init__(**args)
4596
4597    @property
4598    def unit(self) -> Expression:
4599        return self.args["unit"]
DateTrunc(**args)
4586    def __init__(self, **args):
4587        unit = args.get("unit")
4588        if isinstance(unit, TimeUnit.VAR_LIKE):
4589            args["unit"] = Literal.string(
4590                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4591            )
4592        elif isinstance(unit, Week):
4593            unit.set("this", Literal.string(unit.this.name.upper()))
4594
4595        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4597    @property
4598    def unit(self) -> Expression:
4599        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4602class DatetimeAdd(Func, IntervalOp):
4603    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4606class DatetimeSub(Func, IntervalOp):
4607    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4610class DatetimeDiff(Func, TimeUnit):
4611    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4614class DatetimeTrunc(Func, TimeUnit):
4615    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4618class DayOfWeek(Func):
4619    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4622class DayOfMonth(Func):
4623    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4626class DayOfYear(Func):
4627    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4630class ToDays(Func):
4631    pass
key = 'todays'
class WeekOfYear(Func):
4634class WeekOfYear(Func):
4635    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4638class MonthsBetween(Func):
4639    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4642class LastDay(Func, TimeUnit):
4643    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4644    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4647class Extract(Func):
4648    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4651class Timestamp(Func):
4652    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4655class TimestampAdd(Func, TimeUnit):
4656    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4659class TimestampSub(Func, TimeUnit):
4660    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4663class TimestampDiff(Func, TimeUnit):
4664    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4667class TimestampTrunc(Func, TimeUnit):
4668    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4671class TimeAdd(Func, TimeUnit):
4672    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4675class TimeSub(Func, TimeUnit):
4676    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4679class TimeDiff(Func, TimeUnit):
4680    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4683class TimeTrunc(Func, TimeUnit):
4684    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4687class DateFromParts(Func):
4688    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4689    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4692class TimeFromParts(Func):
4693    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4694    arg_types = {
4695        "hour": True,
4696        "min": True,
4697        "sec": True,
4698        "nano": False,
4699        "fractions": False,
4700        "precision": False,
4701    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4704class DateStrToDate(Func):
4705    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4708class DateToDateStr(Func):
4709    pass
key = 'datetodatestr'
class DateToDi(Func):
4712class DateToDi(Func):
4713    pass
key = 'datetodi'
class Date(Func):
4717class Date(Func):
4718    arg_types = {"this": False, "zone": False, "expressions": False}
4719    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4722class Day(Func):
4723    pass
key = 'day'
class Decode(Func):
4726class Decode(Func):
4727    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4730class DiToDate(Func):
4731    pass
key = 'ditodate'
class Encode(Func):
4734class Encode(Func):
4735    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4738class Exp(Func):
4739    pass
key = 'exp'
class Explode(Func):
4743class Explode(Func):
4744    arg_types = {"this": True, "expressions": False}
4745    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4748class ExplodeOuter(Explode):
4749    pass
key = 'explodeouter'
class Posexplode(Explode):
4752class Posexplode(Explode):
4753    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4756class PosexplodeOuter(Posexplode):
4757    pass
key = 'posexplodeouter'
class Floor(Func):
4760class Floor(Func):
4761    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4764class FromBase64(Func):
4765    pass
key = 'frombase64'
class ToBase64(Func):
4768class ToBase64(Func):
4769    pass
key = 'tobase64'
class Greatest(Func):
4772class Greatest(Func):
4773    arg_types = {"this": True, "expressions": False}
4774    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4777class GroupConcat(AggFunc):
4778    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4781class Hex(Func):
4782    pass
key = 'hex'
class Xor(Connector, Func):
4785class Xor(Connector, Func):
4786    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4789class If(Func):
4790    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4793class Nullif(Func):
4794    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4797class Initcap(Func):
4798    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4801class IsNan(Func):
4802    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4805class IsInf(Func):
4806    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4809class FormatJson(Expression):
4810    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4813class JSONKeyValue(Expression):
4814    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4817class JSONObject(Func):
4818    arg_types = {
4819        "expressions": False,
4820        "null_handling": False,
4821        "unique_keys": False,
4822        "return_type": False,
4823        "encoding": False,
4824    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4828class JSONArray(Func):
4829    arg_types = {
4830        "expressions": True,
4831        "null_handling": False,
4832        "return_type": False,
4833        "strict": False,
4834    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4838class JSONArrayAgg(Func):
4839    arg_types = {
4840        "this": True,
4841        "order": False,
4842        "null_handling": False,
4843        "return_type": False,
4844        "strict": False,
4845    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4850class JSONColumnDef(Expression):
4851    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):
4854class JSONSchema(Expression):
4855    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4859class JSONTable(Func):
4860    arg_types = {
4861        "this": True,
4862        "schema": True,
4863        "path": False,
4864        "error_handling": False,
4865        "empty_handling": False,
4866    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4869class OpenJSONColumnDef(Expression):
4870    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):
4873class OpenJSON(Func):
4874    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4877class JSONBContains(Binary):
4878    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4881class JSONExtract(Binary, Func):
4882    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4885class JSONExtractScalar(JSONExtract):
4886    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4889class JSONBExtract(JSONExtract):
4890    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4893class JSONBExtractScalar(JSONExtract):
4894    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4897class JSONFormat(Func):
4898    arg_types = {"this": False, "options": False}
4899    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4903class JSONArrayContains(Binary, Predicate, Func):
4904    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4907class ParseJSON(Func):
4908    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4909    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4910    arg_types = {"this": True, "expressions": False}
4911    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class GetPath(Func):
4915class GetPath(Func):
4916    arg_types = {"this": True, "expression": True}
4917
4918    @property
4919    def output_name(self) -> str:
4920        return self.expression.output_name
arg_types = {'this': True, 'expression': True}
output_name: str
4918    @property
4919    def output_name(self) -> str:
4920        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 = 'getpath'
class Least(Func):
4923class Least(Func):
4924    arg_types = {"this": True, "expressions": False}
4925    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4928class Left(Func):
4929    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4936class Length(Func):
4937    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4940class Levenshtein(Func):
4941    arg_types = {
4942        "this": True,
4943        "expression": False,
4944        "ins_cost": False,
4945        "del_cost": False,
4946        "sub_cost": False,
4947    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4950class Ln(Func):
4951    pass
key = 'ln'
class Log(Func):
4954class Log(Func):
4955    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4958class Log2(Func):
4959    pass
key = 'log2'
class Log10(Func):
4962class Log10(Func):
4963    pass
key = 'log10'
class LogicalOr(AggFunc):
4966class LogicalOr(AggFunc):
4967    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4970class LogicalAnd(AggFunc):
4971    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4974class Lower(Func):
4975    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4978class Map(Func):
4979    arg_types = {"keys": False, "values": False}
4980
4981    @property
4982    def keys(self) -> t.List[Expression]:
4983        keys = self.args.get("keys")
4984        return keys.expressions if keys else []
4985
4986    @property
4987    def values(self) -> t.List[Expression]:
4988        values = self.args.get("values")
4989        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
4981    @property
4982    def keys(self) -> t.List[Expression]:
4983        keys = self.args.get("keys")
4984        return keys.expressions if keys else []
values: List[Expression]
4986    @property
4987    def values(self) -> t.List[Expression]:
4988        values = self.args.get("values")
4989        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
4992class MapFromEntries(Func):
4993    pass
key = 'mapfromentries'
class StarMap(Func):
4996class StarMap(Func):
4997    pass
key = 'starmap'
class VarMap(Func):
5000class VarMap(Func):
5001    arg_types = {"keys": True, "values": True}
5002    is_var_len_args = True
5003
5004    @property
5005    def keys(self) -> t.List[Expression]:
5006        return self.args["keys"].expressions
5007
5008    @property
5009    def values(self) -> t.List[Expression]:
5010        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5004    @property
5005    def keys(self) -> t.List[Expression]:
5006        return self.args["keys"].expressions
values: List[Expression]
5008    @property
5009    def values(self) -> t.List[Expression]:
5010        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5014class MatchAgainst(Func):
5015    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5018class Max(AggFunc):
5019    arg_types = {"this": True, "expressions": False}
5020    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5023class MD5(Func):
5024    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5028class MD5Digest(Func):
5029    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5032class Min(AggFunc):
5033    arg_types = {"this": True, "expressions": False}
5034    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5037class Month(Func):
5038    pass
key = 'month'
class Nvl2(Func):
5041class Nvl2(Func):
5042    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5046class Predict(Func):
5047    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5050class Pow(Binary, Func):
5051    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5054class PercentileCont(AggFunc):
5055    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5058class PercentileDisc(AggFunc):
5059    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5062class Quantile(AggFunc):
5063    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5066class ApproxQuantile(Quantile):
5067    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):
5070class Rand(Func):
5071    _sql_names = ["RAND", "RANDOM"]
5072    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5075class Randn(Func):
5076    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5079class RangeN(Func):
5080    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5083class ReadCSV(Func):
5084    _sql_names = ["READ_CSV"]
5085    is_var_len_args = True
5086    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5089class Reduce(Func):
5090    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):
5093class RegexpExtract(Func):
5094    arg_types = {
5095        "this": True,
5096        "expression": True,
5097        "position": False,
5098        "occurrence": False,
5099        "parameters": False,
5100        "group": False,
5101    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5104class RegexpReplace(Func):
5105    arg_types = {
5106        "this": True,
5107        "expression": True,
5108        "replacement": True,
5109        "position": False,
5110        "occurrence": False,
5111        "parameters": False,
5112        "modifiers": False,
5113    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5116class RegexpLike(Binary, Func):
5117    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5120class RegexpILike(Binary, Func):
5121    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5126class RegexpSplit(Func):
5127    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5130class Repeat(Func):
5131    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5136class Round(Func):
5137    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5140class RowNumber(Func):
5141    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5144class SafeDivide(Func):
5145    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5148class SHA(Func):
5149    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5152class SHA2(Func):
5153    _sql_names = ["SHA2"]
5154    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5157class SortArray(Func):
5158    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5161class Split(Func):
5162    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5167class Substring(Func):
5168    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5171class StandardHash(Func):
5172    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5175class StartsWith(Func):
5176    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5177    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5180class StrPosition(Func):
5181    arg_types = {
5182        "this": True,
5183        "substr": True,
5184        "position": False,
5185        "instance": False,
5186    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5189class StrToDate(Func):
5190    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5193class StrToTime(Func):
5194    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5199class StrToUnix(Func):
5200    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5205class StrToMap(Func):
5206    arg_types = {
5207        "this": True,
5208        "pair_delim": False,
5209        "key_value_delim": False,
5210        "duplicate_resolution_callback": False,
5211    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5214class NumberToStr(Func):
5215    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5218class FromBase(Func):
5219    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5222class Struct(Func):
5223    arg_types = {"expressions": False}
5224    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5227class StructExtract(Func):
5228    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5233class Stuff(Func):
5234    _sql_names = ["STUFF", "INSERT"]
5235    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):
5238class Sum(AggFunc):
5239    pass
key = 'sum'
class Sqrt(Func):
5242class Sqrt(Func):
5243    pass
key = 'sqrt'
class Stddev(AggFunc):
5246class Stddev(AggFunc):
5247    pass
key = 'stddev'
class StddevPop(AggFunc):
5250class StddevPop(AggFunc):
5251    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5254class StddevSamp(AggFunc):
5255    pass
key = 'stddevsamp'
class TimeToStr(Func):
5258class TimeToStr(Func):
5259    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5262class TimeToTimeStr(Func):
5263    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5266class TimeToUnix(Func):
5267    pass
key = 'timetounix'
class TimeStrToDate(Func):
5270class TimeStrToDate(Func):
5271    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5274class TimeStrToTime(Func):
5275    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5278class TimeStrToUnix(Func):
5279    pass
key = 'timestrtounix'
class Trim(Func):
5282class Trim(Func):
5283    arg_types = {
5284        "this": True,
5285        "expression": False,
5286        "position": False,
5287        "collation": False,
5288    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5291class TsOrDsAdd(Func, TimeUnit):
5292    # return_type is used to correctly cast the arguments of this expression when transpiling it
5293    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5294
5295    @property
5296    def return_type(self) -> DataType:
5297        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
5295    @property
5296    def return_type(self) -> DataType:
5297        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5300class TsOrDsDiff(Func, TimeUnit):
5301    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5304class TsOrDsToDateStr(Func):
5305    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5308class TsOrDsToDate(Func):
5309    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5312class TsOrDsToTime(Func):
5313    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5316class TsOrDiToDi(Func):
5317    pass
key = 'tsorditodi'
class Unhex(Func):
5320class Unhex(Func):
5321    pass
key = 'unhex'
class UnixDate(Func):
5325class UnixDate(Func):
5326    pass
key = 'unixdate'
class UnixToStr(Func):
5329class UnixToStr(Func):
5330    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5335class UnixToTime(Func):
5336    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5337
5338    SECONDS = Literal.string("seconds")
5339    MILLIS = Literal.string("millis")
5340    MICROS = Literal.string("micros")
5341    NANOS = Literal.string("nanos")
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False}
SECONDS = Literal(this=seconds, is_string=True)
MILLIS = Literal(this=millis, is_string=True)
MICROS = Literal(this=micros, is_string=True)
NANOS = Literal(this=nanos, is_string=True)
key = 'unixtotime'
class UnixToTimeStr(Func):
5344class UnixToTimeStr(Func):
5345    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5348class TimestampFromParts(Func):
5349    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5350    arg_types = {
5351        "year": True,
5352        "month": True,
5353        "day": True,
5354        "hour": True,
5355        "min": True,
5356        "sec": True,
5357        "nano": False,
5358        "zone": False,
5359        "milli": False,
5360    }
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):
5363class Upper(Func):
5364    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5367class Variance(AggFunc):
5368    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5371class VariancePop(AggFunc):
5372    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5375class Week(Func):
5376    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5379class XMLTable(Func):
5380    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):
5383class Year(Func):
5384    pass
key = 'year'
class Use(Expression):
5387class Use(Expression):
5388    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5391class Merge(Expression):
5392    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5395class When(Func):
5396    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):
5401class NextValueFor(Func):
5402    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <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 'ArrayJoin'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <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 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'GetPath'>, <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 'JSONTable'>, <class 'Last'>, <class 'LastDay'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <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 '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 '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 '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'>, '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_JOIN': <class 'ArrayJoin'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, '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'>, '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'>, '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'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GET_PATH': <class 'GetPath'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <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_TABLE': <class 'JSONTable'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOG10': <class 'Log10'>, 'LOG2': <class 'Log2'>, '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'>, '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'>, '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'>, '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'>, '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'>}
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:
5440def maybe_parse(
5441    sql_or_expression: ExpOrStr,
5442    *,
5443    into: t.Optional[IntoType] = None,
5444    dialect: DialectType = None,
5445    prefix: t.Optional[str] = None,
5446    copy: bool = False,
5447    **opts,
5448) -> Expression:
5449    """Gracefully handle a possible string or expression.
5450
5451    Example:
5452        >>> maybe_parse("1")
5453        Literal(this=1, is_string=False)
5454        >>> maybe_parse(to_identifier("x"))
5455        Identifier(this=x, quoted=False)
5456
5457    Args:
5458        sql_or_expression: the SQL code string or an expression
5459        into: the SQLGlot Expression to parse into
5460        dialect: the dialect used to parse the input expressions (in the case that an
5461            input expression is a SQL string).
5462        prefix: a string to prefix the sql with before it gets parsed
5463            (automatically includes a space)
5464        copy: whether or not to copy the expression.
5465        **opts: other options to use to parse the input expressions (again, in the case
5466            that an input expression is a SQL string).
5467
5468    Returns:
5469        Expression: the parsed or given expression.
5470    """
5471    if isinstance(sql_or_expression, Expression):
5472        if copy:
5473            return sql_or_expression.copy()
5474        return sql_or_expression
5475
5476    if sql_or_expression is None:
5477        raise ParseError(f"SQL cannot be None")
5478
5479    import sqlglot
5480
5481    sql = str(sql_or_expression)
5482    if prefix:
5483        sql = f"{prefix} {sql}"
5484
5485    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 or not 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):
5498def maybe_copy(instance, copy=True):
5499    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:
5713def union(
5714    left: ExpOrStr,
5715    right: ExpOrStr,
5716    distinct: bool = True,
5717    dialect: DialectType = None,
5718    copy: bool = True,
5719    **opts,
5720) -> Union:
5721    """
5722    Initializes a syntax tree from one UNION expression.
5723
5724    Example:
5725        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5726        'SELECT * FROM foo UNION SELECT * FROM bla'
5727
5728    Args:
5729        left: the SQL code string corresponding to the left-hand side.
5730            If an `Expression` instance is passed, it will be used as-is.
5731        right: the SQL code string corresponding to the right-hand side.
5732            If an `Expression` instance is passed, it will be used as-is.
5733        distinct: set the DISTINCT flag if and only if this is true.
5734        dialect: the dialect used to parse the input expression.
5735        copy: whether or not to copy the expression.
5736        opts: other options to use to parse the input expressions.
5737
5738    Returns:
5739        The new Union instance.
5740    """
5741    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5742    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5743
5744    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 or not 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:
5747def intersect(
5748    left: ExpOrStr,
5749    right: ExpOrStr,
5750    distinct: bool = True,
5751    dialect: DialectType = None,
5752    copy: bool = True,
5753    **opts,
5754) -> Intersect:
5755    """
5756    Initializes a syntax tree from one INTERSECT expression.
5757
5758    Example:
5759        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5760        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5761
5762    Args:
5763        left: the SQL code string corresponding to the left-hand side.
5764            If an `Expression` instance is passed, it will be used as-is.
5765        right: the SQL code string corresponding to the right-hand side.
5766            If an `Expression` instance is passed, it will be used as-is.
5767        distinct: set the DISTINCT flag if and only if this is true.
5768        dialect: the dialect used to parse the input expression.
5769        copy: whether or not to copy the expression.
5770        opts: other options to use to parse the input expressions.
5771
5772    Returns:
5773        The new Intersect instance.
5774    """
5775    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5776    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5777
5778    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 or not 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:
5781def except_(
5782    left: ExpOrStr,
5783    right: ExpOrStr,
5784    distinct: bool = True,
5785    dialect: DialectType = None,
5786    copy: bool = True,
5787    **opts,
5788) -> Except:
5789    """
5790    Initializes a syntax tree from one EXCEPT expression.
5791
5792    Example:
5793        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5794        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5795
5796    Args:
5797        left: the SQL code string corresponding to the left-hand side.
5798            If an `Expression` instance is passed, it will be used as-is.
5799        right: the SQL code string corresponding to the right-hand side.
5800            If an `Expression` instance is passed, it will be used as-is.
5801        distinct: set the DISTINCT flag if and only if this is true.
5802        dialect: the dialect used to parse the input expression.
5803        copy: whether or not to copy the expression.
5804        opts: other options to use to parse the input expressions.
5805
5806    Returns:
5807        The new Except instance.
5808    """
5809    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5810    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5811
5812    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 or not 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:
5815def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5816    """
5817    Initializes a syntax tree from one or multiple SELECT expressions.
5818
5819    Example:
5820        >>> select("col1", "col2").from_("tbl").sql()
5821        'SELECT col1, col2 FROM tbl'
5822
5823    Args:
5824        *expressions: the SQL code string to parse as the expressions of a
5825            SELECT statement. If an Expression instance is passed, this is used as-is.
5826        dialect: the dialect used to parse the input expressions (in the case that an
5827            input expression is a SQL string).
5828        **opts: other options to use to parse the input expressions (again, in the case
5829            that an input expression is a SQL string).
5830
5831    Returns:
5832        Select: the syntax tree for the SELECT statement.
5833    """
5834    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:
5837def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5838    """
5839    Initializes a syntax tree from a FROM expression.
5840
5841    Example:
5842        >>> from_("tbl").select("col1", "col2").sql()
5843        'SELECT col1, col2 FROM tbl'
5844
5845    Args:
5846        *expression: the SQL code string to parse as the FROM expressions of a
5847            SELECT statement. If an Expression instance is passed, this is used as-is.
5848        dialect: the dialect used to parse the input expression (in the case that the
5849            input expression is a SQL string).
5850        **opts: other options to use to parse the input expressions (again, in the case
5851            that the input expression is a SQL string).
5852
5853    Returns:
5854        Select: the syntax tree for the SELECT statement.
5855    """
5856    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:
5859def update(
5860    table: str | Table,
5861    properties: dict,
5862    where: t.Optional[ExpOrStr] = None,
5863    from_: t.Optional[ExpOrStr] = None,
5864    dialect: DialectType = None,
5865    **opts,
5866) -> Update:
5867    """
5868    Creates an update statement.
5869
5870    Example:
5871        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5872        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5873
5874    Args:
5875        *properties: dictionary of properties to set which are
5876            auto converted to sql objects eg None -> NULL
5877        where: sql conditional parsed into a WHERE statement
5878        from_: sql statement parsed into a FROM statement
5879        dialect: the dialect used to parse the input expressions.
5880        **opts: other options to use to parse the input expressions.
5881
5882    Returns:
5883        Update: the syntax tree for the UPDATE statement.
5884    """
5885    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5886    update_expr.set(
5887        "expressions",
5888        [
5889            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5890            for k, v in properties.items()
5891        ],
5892    )
5893    if from_:
5894        update_expr.set(
5895            "from",
5896            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5897        )
5898    if isinstance(where, Condition):
5899        where = Where(this=where)
5900    if where:
5901        update_expr.set(
5902            "where",
5903            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5904        )
5905    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:
5908def delete(
5909    table: ExpOrStr,
5910    where: t.Optional[ExpOrStr] = None,
5911    returning: t.Optional[ExpOrStr] = None,
5912    dialect: DialectType = None,
5913    **opts,
5914) -> Delete:
5915    """
5916    Builds a delete statement.
5917
5918    Example:
5919        >>> delete("my_table", where="id > 1").sql()
5920        'DELETE FROM my_table WHERE id > 1'
5921
5922    Args:
5923        where: sql conditional parsed into a WHERE statement
5924        returning: sql conditional parsed into a RETURNING statement
5925        dialect: the dialect used to parse the input expressions.
5926        **opts: other options to use to parse the input expressions.
5927
5928    Returns:
5929        Delete: the syntax tree for the DELETE statement.
5930    """
5931    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5932    if where:
5933        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5934    if returning:
5935        delete_expr = t.cast(
5936            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5937        )
5938    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[Union[str, Expression]]] = 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:
5941def insert(
5942    expression: ExpOrStr,
5943    into: ExpOrStr,
5944    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5945    overwrite: t.Optional[bool] = None,
5946    returning: t.Optional[ExpOrStr] = None,
5947    dialect: DialectType = None,
5948    copy: bool = True,
5949    **opts,
5950) -> Insert:
5951    """
5952    Builds an INSERT statement.
5953
5954    Example:
5955        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5956        'INSERT INTO tbl VALUES (1, 2, 3)'
5957
5958    Args:
5959        expression: the sql string or expression of the INSERT statement
5960        into: the tbl to insert data to.
5961        columns: optionally the table's column names.
5962        overwrite: whether to INSERT OVERWRITE or not.
5963        returning: sql conditional parsed into a RETURNING statement
5964        dialect: the dialect used to parse the input expressions.
5965        copy: whether or not to copy the expression.
5966        **opts: other options to use to parse the input expressions.
5967
5968    Returns:
5969        Insert: the syntax tree for the INSERT statement.
5970    """
5971    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5972    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5973
5974    if columns:
5975        this = _apply_list_builder(
5976            *columns,
5977            instance=Schema(this=this),
5978            arg="expressions",
5979            into=Identifier,
5980            copy=False,
5981            dialect=dialect,
5982            **opts,
5983        )
5984
5985    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5986
5987    if returning:
5988        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5989
5990    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 or not 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:
5993def condition(
5994    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5995) -> Condition:
5996    """
5997    Initialize a logical condition expression.
5998
5999    Example:
6000        >>> condition("x=1").sql()
6001        'x = 1'
6002
6003        This is helpful for composing larger logical syntax trees:
6004        >>> where = condition("x=1")
6005        >>> where = where.and_("y=1")
6006        >>> Select().from_("tbl").select("*").where(where).sql()
6007        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6008
6009    Args:
6010        *expression: the SQL code string to parse.
6011            If an Expression instance is passed, this is used as-is.
6012        dialect: the dialect used to parse the input expression (in the case that the
6013            input expression is a SQL string).
6014        copy: Whether or not to copy `expression` (only applies to expressions).
6015        **opts: other options to use to parse the input expressions (again, in the case
6016            that the input expression is a SQL string).
6017
6018    Returns:
6019        The new Condition instance
6020    """
6021    return maybe_parse(
6022        expression,
6023        into=Condition,
6024        dialect=dialect,
6025        copy=copy,
6026        **opts,
6027    )

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 or not 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:
6030def and_(
6031    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6032) -> Condition:
6033    """
6034    Combine multiple conditions with an AND logical operator.
6035
6036    Example:
6037        >>> and_("x=1", and_("y=1", "z=1")).sql()
6038        'x = 1 AND (y = 1 AND z = 1)'
6039
6040    Args:
6041        *expressions: the SQL code strings to parse.
6042            If an Expression instance is passed, this is used as-is.
6043        dialect: the dialect used to parse the input expression.
6044        copy: whether or not to copy `expressions` (only applies to Expressions).
6045        **opts: other options to use to parse the input expressions.
6046
6047    Returns:
6048        And: the new condition
6049    """
6050    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 or not 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:
6053def or_(
6054    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6055) -> Condition:
6056    """
6057    Combine multiple conditions with an OR logical operator.
6058
6059    Example:
6060        >>> or_("x=1", or_("y=1", "z=1")).sql()
6061        'x = 1 OR (y = 1 OR z = 1)'
6062
6063    Args:
6064        *expressions: the SQL code strings to parse.
6065            If an Expression instance is passed, this is used as-is.
6066        dialect: the dialect used to parse the input expression.
6067        copy: whether or not to copy `expressions` (only applies to Expressions).
6068        **opts: other options to use to parse the input expressions.
6069
6070    Returns:
6071        Or: the new condition
6072    """
6073    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 or not 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:
6076def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6077    """
6078    Wrap a condition with a NOT operator.
6079
6080    Example:
6081        >>> not_("this_suit='black'").sql()
6082        "NOT this_suit = 'black'"
6083
6084    Args:
6085        expression: the SQL code string to parse.
6086            If an Expression instance is passed, this is used as-is.
6087        dialect: the dialect used to parse the input expression.
6088        copy: whether to copy the expression or not.
6089        **opts: other options to use to parse the input expressions.
6090
6091    Returns:
6092        The new condition.
6093    """
6094    this = condition(
6095        expression,
6096        dialect=dialect,
6097        copy=copy,
6098        **opts,
6099    )
6100    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:
6103def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6104    """
6105    Wrap an expression in parentheses.
6106
6107    Example:
6108        >>> paren("5 + 3").sql()
6109        '(5 + 3)'
6110
6111    Args:
6112        expression: the SQL code string to parse.
6113            If an Expression instance is passed, this is used as-is.
6114        copy: whether to copy the expression or not.
6115
6116    Returns:
6117        The wrapped expression.
6118    """
6119    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 = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
6137def to_identifier(name, quoted=None, copy=True):
6138    """Builds an identifier.
6139
6140    Args:
6141        name: The name to turn into an identifier.
6142        quoted: Whether or not force quote the identifier.
6143        copy: Whether or not to copy name if it's an Identifier.
6144
6145    Returns:
6146        The identifier ast node.
6147    """
6148
6149    if name is None:
6150        return None
6151
6152    if isinstance(name, Identifier):
6153        identifier = maybe_copy(name, copy)
6154    elif isinstance(name, str):
6155        identifier = Identifier(
6156            this=name,
6157            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6158        )
6159    else:
6160        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6161    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether or not force quote the identifier.
  • copy: Whether or not 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:
6164def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6165    """
6166    Parses a given string into an identifier.
6167
6168    Args:
6169        name: The name to parse into an identifier.
6170        dialect: The dialect to parse against.
6171
6172    Returns:
6173        The identifier ast node.
6174    """
6175    try:
6176        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6177    except ParseError:
6178        expression = to_identifier(name)
6179
6180    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:
6186def to_interval(interval: str | Literal) -> Interval:
6187    """Builds an interval expression from a string like '1 day' or '5 months'."""
6188    if isinstance(interval, Literal):
6189        if not interval.is_string:
6190            raise ValueError("Invalid interval string.")
6191
6192        interval = interval.this
6193
6194    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6195
6196    if not interval_parts:
6197        raise ValueError("Invalid interval string.")
6198
6199    return Interval(
6200        this=Literal.string(interval_parts.group(1)),
6201        unit=Var(this=interval_parts.group(2).upper()),
6202    )

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]:
6215def to_table(
6216    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6217) -> t.Optional[Table]:
6218    """
6219    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6220    If a table is passed in then that table is returned.
6221
6222    Args:
6223        sql_path: a `[catalog].[schema].[table]` string.
6224        dialect: the source dialect according to which the table name will be parsed.
6225        copy: Whether or not to copy a table if it is passed in.
6226        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6227
6228    Returns:
6229        A table expression.
6230    """
6231    if sql_path is None or isinstance(sql_path, Table):
6232        return maybe_copy(sql_path, copy=copy)
6233    if not isinstance(sql_path, str):
6234        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6235
6236    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6237    if table:
6238        for k, v in kwargs.items():
6239            table.set(k, v)
6240
6241    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 or not 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:
6244def to_column(sql_path: str | Column, **kwargs) -> Column:
6245    """
6246    Create a column from a `[table].[column]` sql path. Schema is optional.
6247
6248    If a column is passed in then that column is returned.
6249
6250    Args:
6251        sql_path: `[table].[column]` string
6252    Returns:
6253        Table: A column expression
6254    """
6255    if sql_path is None or isinstance(sql_path, Column):
6256        return sql_path
6257    if not isinstance(sql_path, str):
6258        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6259    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: str | Identifier, 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):
6262def alias_(
6263    expression: ExpOrStr,
6264    alias: str | Identifier,
6265    table: bool | t.Sequence[str | Identifier] = False,
6266    quoted: t.Optional[bool] = None,
6267    dialect: DialectType = None,
6268    copy: bool = True,
6269    **opts,
6270):
6271    """Create an Alias expression.
6272
6273    Example:
6274        >>> alias_('foo', 'bar').sql()
6275        'foo AS bar'
6276
6277        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6278        '(SELECT 1, 2) AS bar(a, b)'
6279
6280    Args:
6281        expression: the SQL code strings to parse.
6282            If an Expression instance is passed, this is used as-is.
6283        alias: the alias name to use. If the name has
6284            special characters it is quoted.
6285        table: Whether or not to create a table alias, can also be a list of columns.
6286        quoted: whether or not to quote the alias
6287        dialect: the dialect used to parse the input expression.
6288        copy: Whether or not to copy the expression.
6289        **opts: other options to use to parse the input expressions.
6290
6291    Returns:
6292        Alias: the aliased expression
6293    """
6294    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6295    alias = to_identifier(alias, quoted=quoted)
6296
6297    if table:
6298        table_alias = TableAlias(this=alias)
6299        exp.set("alias", table_alias)
6300
6301        if not isinstance(table, bool):
6302            for column in table:
6303                table_alias.append("columns", to_identifier(column, quoted=quoted))
6304
6305        return exp
6306
6307    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6308    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6309    # for the complete Window expression.
6310    #
6311    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6312
6313    if "alias" in exp.arg_types and not isinstance(exp, Window):
6314        exp.set("alias", alias)
6315        return exp
6316    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 or not to create a table alias, can also be a list of columns.
  • quoted: whether or not to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether or not 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:
6319def subquery(
6320    expression: ExpOrStr,
6321    alias: t.Optional[Identifier | str] = None,
6322    dialect: DialectType = None,
6323    **opts,
6324) -> Select:
6325    """
6326    Build a subquery expression.
6327
6328    Example:
6329        >>> subquery('select x from tbl', 'bar').select('x').sql()
6330        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6331
6332    Args:
6333        expression: the SQL code strings to parse.
6334            If an Expression instance is passed, this is used as-is.
6335        alias: the alias name to use.
6336        dialect: the dialect used to parse the input expression.
6337        **opts: other options to use to parse the input expressions.
6338
6339    Returns:
6340        A new Select instance with the subquery expression included.
6341    """
6342
6343    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6344    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression.

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):
6375def column(
6376    col,
6377    table=None,
6378    db=None,
6379    catalog=None,
6380    *,
6381    fields=None,
6382    quoted=None,
6383    copy=True,
6384):
6385    """
6386    Build a Column.
6387
6388    Args:
6389        col: Column name.
6390        table: Table name.
6391        db: Database name.
6392        catalog: Catalog name.
6393        fields: Additional fields using dots.
6394        quoted: Whether to force quotes on the column's identifiers.
6395        copy: Whether or not to copy identifiers if passed in.
6396
6397    Returns:
6398        The new Column instance.
6399    """
6400    this = Column(
6401        this=to_identifier(col, quoted=quoted, copy=copy),
6402        table=to_identifier(table, quoted=quoted, copy=copy),
6403        db=to_identifier(db, quoted=quoted, copy=copy),
6404        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6405    )
6406
6407    if fields:
6408        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6409    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 or not to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], **opts) -> Cast:
6412def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6413    """Cast an expression to a data type.
6414
6415    Example:
6416        >>> cast('x + 1', 'int').sql()
6417        'CAST(x + 1 AS INT)'
6418
6419    Args:
6420        expression: The expression to cast.
6421        to: The datatype to cast to.
6422
6423    Returns:
6424        The new Cast instance.
6425    """
6426    expression = maybe_parse(expression, **opts)
6427    data_type = DataType.build(to, **opts)
6428    expression = Cast(this=expression, to=data_type)
6429    expression.type = data_type
6430    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.
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:
6433def table_(
6434    table: Identifier | str,
6435    db: t.Optional[Identifier | str] = None,
6436    catalog: t.Optional[Identifier | str] = None,
6437    quoted: t.Optional[bool] = None,
6438    alias: t.Optional[Identifier | str] = None,
6439) -> Table:
6440    """Build a Table.
6441
6442    Args:
6443        table: Table name.
6444        db: Database name.
6445        catalog: Catalog name.
6446        quote: Whether to force quotes on the table's identifiers.
6447        alias: Table's alias.
6448
6449    Returns:
6450        The new Table instance.
6451    """
6452    return Table(
6453        this=to_identifier(table, quoted=quoted) if table else None,
6454        db=to_identifier(db, quoted=quoted) if db else None,
6455        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6456        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6457    )

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:
6460def values(
6461    values: t.Iterable[t.Tuple[t.Any, ...]],
6462    alias: t.Optional[str] = None,
6463    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6464) -> Values:
6465    """Build VALUES statement.
6466
6467    Example:
6468        >>> values([(1, '2')]).sql()
6469        "VALUES (1, '2')"
6470
6471    Args:
6472        values: values statements that will be converted to SQL
6473        alias: optional alias
6474        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6475         If either are provided then an alias is also required.
6476
6477    Returns:
6478        Values: the Values expression object
6479    """
6480    if columns and not alias:
6481        raise ValueError("Alias is required when providing columns")
6482
6483    return Values(
6484        expressions=[convert(tup) for tup in values],
6485        alias=(
6486            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6487            if columns
6488            else (TableAlias(this=to_identifier(alias)) if alias else None)
6489        ),
6490    )

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:
6493def var(name: t.Optional[ExpOrStr]) -> Var:
6494    """Build a SQL variable.
6495
6496    Example:
6497        >>> repr(var('x'))
6498        'Var(this=x)'
6499
6500        >>> repr(var(column('x', table='y')))
6501        'Var(this=x)'
6502
6503    Args:
6504        name: The name of the var or an expression who's name will become the var.
6505
6506    Returns:
6507        The new variable node.
6508    """
6509    if not name:
6510        raise ValueError("Cannot convert empty name into var.")
6511
6512    if isinstance(name, Expression):
6513        name = name.name
6514    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:
6517def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6518    """Build ALTER TABLE... RENAME... expression
6519
6520    Args:
6521        old_name: The old name of the table
6522        new_name: The new name of the table
6523
6524    Returns:
6525        Alter table expression
6526    """
6527    old_table = to_table(old_name)
6528    new_table = to_table(new_name)
6529    return AlterTable(
6530        this=old_table,
6531        actions=[
6532            RenameTable(this=new_table),
6533        ],
6534    )

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 convert(value: Any, copy: bool = False) -> Expression:
6537def convert(value: t.Any, copy: bool = False) -> Expression:
6538    """Convert a python value into an expression object.
6539
6540    Raises an error if a conversion is not possible.
6541
6542    Args:
6543        value: A python object.
6544        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6545
6546    Returns:
6547        Expression: the equivalent expression object.
6548    """
6549    if isinstance(value, Expression):
6550        return maybe_copy(value, copy)
6551    if isinstance(value, str):
6552        return Literal.string(value)
6553    if isinstance(value, bool):
6554        return Boolean(this=value)
6555    if value is None or (isinstance(value, float) and math.isnan(value)):
6556        return NULL
6557    if isinstance(value, numbers.Number):
6558        return Literal.number(value)
6559    if isinstance(value, datetime.datetime):
6560        datetime_literal = Literal.string(
6561            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6562        )
6563        return TimeStrToTime(this=datetime_literal)
6564    if isinstance(value, datetime.date):
6565        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6566        return DateStrToDate(this=date_literal)
6567    if isinstance(value, tuple):
6568        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6569    if isinstance(value, list):
6570        return Array(expressions=[convert(v, copy=copy) for v in value])
6571    if isinstance(value, dict):
6572        return Map(
6573            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6574            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6575        )
6576    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 or not 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:
6579def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6580    """
6581    Replace children of an expression with the result of a lambda fun(child) -> exp.
6582    """
6583    for k, v in expression.args.items():
6584        is_list_arg = type(v) is list
6585
6586        child_nodes = v if is_list_arg else [v]
6587        new_child_nodes = []
6588
6589        for cn in child_nodes:
6590            if isinstance(cn, Expression):
6591                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6592                    new_child_nodes.append(child_node)
6593                    child_node.parent = expression
6594                    child_node.arg_key = k
6595            else:
6596                new_child_nodes.append(cn)
6597
6598        expression.args[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 column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
6601def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6602    """
6603    Return all table names referenced through columns in an expression.
6604
6605    Example:
6606        >>> import sqlglot
6607        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6608        ['a', 'c']
6609
6610    Args:
6611        expression: expression to find table names.
6612        exclude: a table name to exclude
6613
6614    Returns:
6615        A list of unique names.
6616    """
6617    return {
6618        table
6619        for table in (column.table for column in expression.find_all(Column))
6620        if table and table != exclude
6621    }

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:
6624def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6625    """Get the full name of a table as a string.
6626
6627    Args:
6628        table: Table expression node or string.
6629        dialect: The dialect to generate the table name for.
6630        identify: Determines when an identifier should be quoted. Possible values are:
6631            False (default): Never quote, except in cases where it's mandatory by the dialect.
6632            True: Always quote.
6633
6634    Examples:
6635        >>> from sqlglot import exp, parse_one
6636        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6637        'a.b.c'
6638
6639    Returns:
6640        The table name.
6641    """
6642
6643    table = maybe_parse(table, into=Table, dialect=dialect)
6644
6645    if not table:
6646        raise ValueError(f"Cannot parse {table}")
6647
6648    return ".".join(
6649        part.sql(dialect=dialect, identify=True, copy=False)
6650        if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6651        else part.name
6652        for part in table.parts
6653    )

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:
6656def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6657    """Returns a case normalized table name without quotes.
6658
6659    Args:
6660        table: the table to normalize
6661        dialect: the dialect to use for normalization rules
6662        copy: whether or not to copy the expression.
6663
6664    Examples:
6665        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6666        'A-B.c'
6667    """
6668    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6669
6670    return ".".join(
6671        p.name
6672        for p in normalize_identifiers(
6673            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6674        ).parts
6675    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether or not 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:
6678def replace_tables(
6679    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6680) -> E:
6681    """Replace all tables in expression according to the mapping.
6682
6683    Args:
6684        expression: expression node to be transformed and replaced.
6685        mapping: mapping of table names.
6686        dialect: the dialect of the mapping table
6687        copy: whether or not to copy the expression.
6688
6689    Examples:
6690        >>> from sqlglot import exp, parse_one
6691        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6692        'SELECT * FROM c /* a.b */'
6693
6694    Returns:
6695        The mapped expression.
6696    """
6697
6698    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6699
6700    def _replace_tables(node: Expression) -> Expression:
6701        if isinstance(node, Table):
6702            original = normalize_table_name(node, dialect=dialect)
6703            new_name = mapping.get(original)
6704
6705            if new_name:
6706                table = to_table(
6707                    new_name,
6708                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6709                )
6710                table.add_comments([original])
6711                return table
6712        return node
6713
6714    return expression.transform(_replace_tables, copy=copy)

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 or not 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:
6717def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6718    """Replace placeholders in an expression.
6719
6720    Args:
6721        expression: expression node to be transformed and replaced.
6722        args: positional names that will substitute unnamed placeholders in the given order.
6723        kwargs: keyword arguments that will substitute named placeholders.
6724
6725    Examples:
6726        >>> from sqlglot import exp, parse_one
6727        >>> replace_placeholders(
6728        ...     parse_one("select * from :tbl where ? = ?"),
6729        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6730        ... ).sql()
6731        "SELECT * FROM foo WHERE str_col = 'b'"
6732
6733    Returns:
6734        The mapped expression.
6735    """
6736
6737    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6738        if isinstance(node, Placeholder):
6739            if node.name:
6740                new_name = kwargs.get(node.name)
6741                if new_name:
6742                    return convert(new_name)
6743            else:
6744                try:
6745                    return convert(next(args))
6746                except StopIteration:
6747                    pass
6748        return node
6749
6750    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, Subqueryable], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
6753def expand(
6754    expression: Expression,
6755    sources: t.Dict[str, Subqueryable],
6756    dialect: DialectType = None,
6757    copy: bool = True,
6758) -> Expression:
6759    """Transforms an expression by expanding all referenced sources into subqueries.
6760
6761    Examples:
6762        >>> from sqlglot import parse_one
6763        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6764        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6765
6766        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6767        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6768
6769    Args:
6770        expression: The expression to expand.
6771        sources: A dictionary of name to Subqueryables.
6772        dialect: The dialect of the sources dict.
6773        copy: Whether or not to copy the expression during transformation. Defaults to True.
6774
6775    Returns:
6776        The transformed expression.
6777    """
6778    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6779
6780    def _expand(node: Expression):
6781        if isinstance(node, Table):
6782            name = normalize_table_name(node, dialect=dialect)
6783            source = sources.get(name)
6784            if source:
6785                subquery = source.subquery(node.alias or name)
6786                subquery.comments = [f"source: {name}"]
6787                return subquery.transform(_expand, copy=False)
6788        return node
6789
6790    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 Subqueryables.
  • dialect: The dialect of the sources dict.
  • copy: Whether or not 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:
6793def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6794    """
6795    Returns a Func expression.
6796
6797    Examples:
6798        >>> func("abs", 5).sql()
6799        'ABS(5)'
6800
6801        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6802        'CAST(5 AS DOUBLE)'
6803
6804    Args:
6805        name: the name of the function to build.
6806        args: the args used to instantiate the function of interest.
6807        copy: whether or not to copy the argument expressions.
6808        dialect: the source dialect.
6809        kwargs: the kwargs used to instantiate the function of interest.
6810
6811    Note:
6812        The arguments `args` and `kwargs` are mutually exclusive.
6813
6814    Returns:
6815        An instance of the function of interest, or an anonymous function, if `name` doesn't
6816        correspond to an existing `sqlglot.expressions.Func` class.
6817    """
6818    if args and kwargs:
6819        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6820
6821    from sqlglot.dialects.dialect import Dialect
6822
6823    dialect = Dialect.get_or_raise(dialect)
6824
6825    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6826    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6827
6828    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6829    if constructor:
6830        if converted:
6831            if "dialect" in constructor.__code__.co_varnames:
6832                function = constructor(converted, dialect=dialect)
6833            else:
6834                function = constructor(converted)
6835        elif constructor.__name__ == "from_arg_list":
6836            function = constructor.__self__(**kwargs)  # type: ignore
6837        else:
6838            constructor = FUNCTION_BY_NAME.get(name.upper())
6839            if constructor:
6840                function = constructor(**kwargs)
6841            else:
6842                raise ValueError(
6843                    f"Unable to convert '{name}' into a Func. Either manually construct "
6844                    "the Func expression of interest or parse the function call."
6845                )
6846    else:
6847        kwargs = kwargs or {"expressions": converted}
6848        function = Anonymous(this=name, **kwargs)
6849
6850    for error_message in function.error_messages(converted):
6851        raise ValueError(error_message)
6852
6853    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 or not 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:
6856def case(
6857    expression: t.Optional[ExpOrStr] = None,
6858    **opts,
6859) -> Case:
6860    """
6861    Initialize a CASE statement.
6862
6863    Example:
6864        case().when("a = 1", "foo").else_("bar")
6865
6866    Args:
6867        expression: Optionally, the input expression (not all dialects support this)
6868        **opts: Extra keyword arguments for parsing `expression`
6869    """
6870    if expression is not None:
6871        this = maybe_parse(expression, **opts)
6872    else:
6873        this = None
6874    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:
6877def cast_unless(
6878    expression: ExpOrStr,
6879    to: DATA_TYPE,
6880    *types: DATA_TYPE,
6881    **opts: t.Any,
6882) -> Expression | Cast:
6883    """
6884    Cast an expression to a data type unless it is a specified type.
6885
6886    Args:
6887        expression: The expression to cast.
6888        to: The data type to cast to.
6889        **types: The types to exclude from casting.
6890        **opts: Extra keyword arguments for parsing `expression`
6891    """
6892    expr = maybe_parse(expression, **opts)
6893    if expr.is_type(*types):
6894        return expr
6895    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 true() -> Boolean:
6898def true() -> Boolean:
6899    """
6900    Returns a true Boolean expression.
6901    """
6902    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6905def false() -> Boolean:
6906    """
6907    Returns a false Boolean expression.
6908    """
6909    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6912def null() -> Null:
6913    """
6914    Returns a Null expression.
6915    """
6916    return Null()

Returns a Null expression.

TRUE = Boolean(this=True)
FALSE = Boolean(this=False)
NULL = Null()